我有一个课我需要一个简单的工厂方法:
class GTree{
public static createNode(){
return new GNode();
}
}
这意味着我不想让消费者立即实例化GNode。
如何正确实施?
显然我不能这样做:
class GNode{
constructor(){
throw TypeError("This is nonsense");
}
}
因为那时我根本无法创建节点 我如何强行使用工厂?
答案 0 :(得分:2)
你无法在javascript中真正做到这一点,但你可以这样做:
export class GTree {
public static createNode(name: string): GNode {
return new GNodeImpl(name);
}
}
export interface GNode {
name: string;
}
class GNodeImpl implements GNode {
constructor(public name: string) {}
}
仅导出GTree
和GNode
接口,这意味着无法从模块外部实例化GNodeImpl
。
我为示例添加了name
属性。
答案 1 :(得分:2)
这是一个比我之前的评论更简单的方案。只需在私有(但共享)范围内定义GNode
类,这样就可以调用构造函数的唯一位置,并重置.constructor
属性,因此它不会漏出来了:
const GTree = (function() {
class GNode {
constructor() {
}
someOtherMethod() {
console.log("someOtherMethod");
}
}
// reset public .constructor
GNode.prototype.constructor = function() {
throw new Error("Can't call GNode constructor directly");
};
class GTree {
constructor() {
this.nodes = [];
}
createNode() {
let node = new GNode();
this.nodes.push(node);
return node;
}
get length() {
return this.nodes.length;
}
}
return GTree;
})();
let tree = new GTree();
let node1 = tree.createNode();
let node2 = tree.createNode();
node1.someOtherMethod();
console.log(tree.length + " nodes");