在工厂类中实现继承而不复制Javascript中的代码
这个问题包括一些数学概念,但它们与问题的实质无关 我正在实现一个API来研究图上的自动机。我有一个名为AutomataGraph的抽象类,它由我感兴趣的不同类型的AutomataGraph继承。每种类型都有不同的规则来说明它是如何在状态中前进的。对于每种类型,我都有一个从AutomataGraphBuilder继承的builder/factory类,用于对图形/自动机执行不同有趣的操作。其中之一就是生成所有具有n个节点的未标记图。在AutomaGraphBuilder类中,此方法类似于:在工厂类中实现继承而不复制Javascript中的代码,javascript,oop,inheritance,structure,factory,Javascript,Oop,Inheritance,Structure,Factory,这个问题包括一些数学概念,但它们与问题的实质无关 我正在实现一个API来研究图上的自动机。我有一个名为AutomataGraph的抽象类,它由我感兴趣的不同类型的AutomataGraph继承。每种类型都有不同的规则来说明它是如何在状态中前进的。对于每种类型,我都有一个从AutomataGraphBuilder继承的builder/factory类,用于对图形/自动机执行不同有趣的操作。其中之一就是生成所有具有n个节点的未标记图。在AutomaGraphBuilder类中,此方法类似于: Aut
AutomataGraphBuilder.prototype.genAllUnlabeledGraphs = function(n){
var graphs = [];
var graph;
for(all possible graphs){
graph = new AutomataGraph();
if (should add graph) {
graphs.push(graph);
}
}
return graphs;
}
这很好,除非我想将此调用扩展到johncowayautomatagraphbuilder,我必须复制所有代码,以便将“graph=new AutomataGraph()”行更改为“graph=new johncowayautomatagraph()”
有什么建议吗?我更感兴趣的是寻找一些一般的结构见解,而不是这是javascript
编辑:伪代码当然与实际算法大不相同,只是为了证明存在过多的代码复制。基本上,通过一个允许创建新实例的功能(在js中,这只是构造函数),您可以从生成器类和item类中获得一个链接 然后,
johncowayautomatagraphbuilder
将只是一个覆盖.itemConstructor
属性的子类(或某个不相关的类,它只共享该方法,并且有一个指向其他地方的.itemConstructor
属性)
另一种方法是使用闭包,动态创建
generate
方法:
function makeGraphGenerator(constructor) {
return function(n) {
var graphs = [];
for(all possible graphs){
var graph = new constructor(args);
if (should add graph) {
graphs.push(graph);
}
}
return graphs;
};
}
AutomataGraphBuilder.prototype.genAllUnlabeledGraphs = makeGraphGenerator(AutomataGraph);
JohnConwayAutomataGraphBuilder.prototype.… = makeGraphGenerator(…);
唯一更改的代码是否总是为每个混凝土工厂创建的
自动绘图类型?参数(args
)来自哪里?它们是硬编码的吗?它们总是一样的吗?实际上没有传递任何参数;那是个错误。唯一改变的是型号。看来你们的工厂也太多了。它应该只知道如何实例化一个AutomataGraph
,其余的不应该是它关心的。另一个对象可能负责genAllUnlabeledGraphs
,并依赖注入的工厂来创建AutomataGraph
实例。@plalx:我想这只是不好的命名约定,OPsAutomataGraphBuilder
似乎没有用于构建Automatagraphs
s的功能。您能推荐一个替代方案吗?我喜欢这个答案。这与java/c++有相似之处吗?这似乎是对继承的错误/不必要的使用。这家工厂做得太多了。另一个对象应该负责genAllUnlabeledGraphs
,并且应该向其中注入工厂,以确保它确实实例化了正确的类。设计会简单得多,不是吗?也许我不想让工厂课程成为教科书意义上的课程,所以我应该改变标题。我只需要一个类来处理对象集的创建和操作。这就是我所假设的工厂类的用途:操作/创建对象。@plalx:如果您有继承设置(有问题的类名建议这样做),这对我来说似乎是合理的。当然,另一种解决方案是只将工厂作为第二个参数的方法(可能部分应用)。
function makeGraphGenerator(constructor) {
return function(n) {
var graphs = [];
for(all possible graphs){
var graph = new constructor(args);
if (should add graph) {
graphs.push(graph);
}
}
return graphs;
};
}
AutomataGraphBuilder.prototype.genAllUnlabeledGraphs = makeGraphGenerator(AutomataGraph);
JohnConwayAutomataGraphBuilder.prototype.… = makeGraphGenerator(…);