我有一个类层次结构,如:
|-> Square
AbstractShape -+-> Circle
|-> Triangle
现在,我想实现策略模式并创建一个存储在字符串中的类对象。在PHP中我会使用:
$type = 'Square';
$obj = new $type();
Node.js中有等价物吗?
如果您希望采用更强大且可测试的方法,则可以使用类和工厂模式的组合来发布对象。查看以下内容,您将看到通过此设置,包括更精细的逻辑和测试将更容易,并提供更大的灵活性。你也在.issue
调用背后自己抽象出对象 - 这在某些情况下可能是有益和方便的。
我还注意到你提到了你的PHP背景,所以我还展示了一些如何在ES6中采用面向对象的方法。
class AbstractShape {
constructor(type) {
this.type = type;
}
getType() {
console.log(`I am a ${this.type}`);
}
}
class Square extends AbstractShape {
constructor(type) {
super(type);
this.sides = 4;
}
getDescription() {
console.log(`I have ${this.sides} equal sides`);
}
}
class ShapeFactory {
static issue(type) {
switch(type) {
case 'Square': return new Square(type);
break;
case 'Circle': /* same pattern with a Circle class */
break;
}
}
}
let shape = ShapeFactory.issue('Square');
shape.getType(); /* I am a Square */
shape.getDescription(); /* I have 4 equal sides */
Z zxswでも-but
此外,如果您想要比处理冗余字符串更容错一些,例如JSFiddle Link - 'Square'
利用类似枚举的方法,可以进一步完善这一点。我将在这里保存房地产而不是重新哈希代码片段,但会包含一个小提琴供您查看。
there are some creative ways - enum方法演示
一种安全的方法是定义工厂对象:
JSFiddle Link
function Square() {
}
// here other constructors for Circle and Triangle
var factory = {
"Square": Square,
"Circle": Circle,
"Triangle" : Triangle
}
var typeName;
// here some code which sets typeName
var typeObj = new factory[typeName]();
。但强烈建议不要使用它,原因很多 - 安全性,性能,可读性和可支持性
eval
function MyType() {
}
var typeName = 'MyType';
var typeObj = eval('new ' + typeName + '()');
更安全和更正确的是使用字符串名称到类型的映射(感谢@GaloisGecko)
eval
function createType(name) {
var types = {
"Square": Square,
"Circle": Circle,
"Triangle": Tringle
};
return types.hasOwnProperty(name) ? new types[name]() : null;
}
。你也可以找到很好的描述和例子@scniro answer经过仔细考虑,Node.js有一个非常简单的方法。当你以最简单的方式实例化一个对象时,你实际上写了here,其中new <variableName>
是一些函数或类的主体,在某个模块中定义和导出。要将此函数/类分配给变量,您需要variableName
。
所以,而不是
require()
你需要写:
const type = 'Square';
const aSquare = new type();
一个小的缺点是,eslint抱怨(在某些规则设置中)const type = 'Square';
const shape = require(`${pathToShapeModules}/${type}.js`);
const aShape = new shape();
s将被放置在模块的顶部。当然,它需要通过尝试...捕获等进行适当的异常处理。所以可能工厂解决方案更好(所以我将接受它)但我认为对于小型专业案例,这个解决方案是可以的。