我在重构一段代码时遇到一个案例,该代码要求我在nodejs中使用对象工厂模式。因此,我在示例代码中尝试了这种模式,并提出了一些疑问。
factoryTest.js
var createFactory = require("./createFactory").createObjects();
var helloWorldObject = createFactory.helloWorld("userOne");
console.log("helloWorldObject: "+JSON.stringify(helloWorldObject));
var byeWorldObject = createFactory.byeWorld("userTwo", 22);
console.log("helloWorldObject: "+JSON.stringify(helloWorldObject));
console.log("byeWorldObject: "+JSON.stringify(byeWorldObject));
createFactory.js
var createObjects = function() {
console.log("received a request to create new object.")
this.localObject = {};
};
createObjects.prototype.helloWorld = function(name){
this.localObject = {}; // CASE 1 <<<--- how can this be removed?
this.localObject.name = name;
this.localObject.greeting = "Hello " +name;
return this.localObject;
};
createObjects.prototype.byeWorld = function(name, age){
this.localObject = {}; // CASE 2 <<<--- how can this be removed?
this.localObject.name = name;
this.localObject.age= age;
this.localObject.greeting = "Bye " +name;
return this.localObject;
};
exports.createObjects = function(){
return new createObjects();
}
CASE1和CASE2保持原样时的输出
received a request to create new object.
helloWorldObject: {"name":"userOne","greeting":"Hello userOne"}
helloWorldObject: {"name":"userOne","greeting":"Hello userOne"}
byeWorldObject: {"name":"userTwo","age":22,"greeting":"Bye userTwo"}
删除CASE1和CASE2时的输出
received a request to create new object.
helloWorldObject: {"name":"userOne","greeting":"Hello userOne"}
helloWorldObject: {"name":"userTwo","greeting":"Bye userTwo","age":22}
byeWorldObject: {"name":"userTwo","greeting":"Bye userTwo","age":22}
新版本:
createFactory.js
var objectFactory = function(){
console.log("received a new factory request.")
return new createObjects();
}
var createObjects = function() {
console.log("received a request to create new object.");
this.localObject = {};
};
createObjects.prototype.helloWorld = function(name){
this.localObject.name = name;
this.localObject.greeting = "Hello " +name;
return this.localObject;
};
createObjects.prototype.byeWorld = function(name, age){
this.localObject.name = name;
this.localObject.age = age;
this.localObject.greeting = "Bye " +name;
return this.localObject;
};
module.exports.objectFactory = objectFactory;
factoryTest.js
var createFactory = require("./createFactory").objectFactory;
var helloWorldObject = createFactory().helloWorld("userOne");
console.log("helloWorldObject: "+JSON.stringify(helloWorldObject));
var byeWorldObject = createFactory().byeWorld("userTwo", 22);
console.log("helloWorldObject: "+JSON.stringify(helloWorldObject));
console.log("byeWorldObject: "+JSON.stringify(byeWorldObject));
输出
received a new factory request.
received a request to create new object.
helloWorldObject: {"name":"userOne","greeting":"Hello userOne"}
received a new factory request.
received a request to create new object.
helloWorldObject: {"name":"userOne","greeting":"Hello userOne"}
byeWorldObject: {"name":"userTwo","age":22,"greeting":"Bye userTwo"}
这种方法能消除问题吗?
很高兴知道,该Factory
模式实际上会创建对象。它不用于以任何方式重用它们。
如果要重用它们,则应使用所谓的object pool
。
现在,您的代码中存在一些问题。一切都从这里开始:
exports.createObjects = function(){
return new createObjects();
}
因此,第一次使用时require("./createFactory").createObjects()
,该函数将被执行并创建新工厂。现在,每次使用该工厂时,都将开始使用相同的对象- this.localObject
。这意味着您没有项目的集合,而不是每次使用helloWorld
或时都更改一个项目byeWorld
。
this.localObject.name = name;
您实际上不是在创建新对象,而是使用已经创建的对象并更改其属性。如果您确实需要创建新对象,则类似以下内容可能会有所帮助:
function createObjects() {
this.objects = []; // store collection of objects
}
createObjects.prototype.helloWorld = function(name) {
var obj = {
name: name,
greeting: "Hello " + name
}
this.objects.push(obj);
return obj;
}
这将创建新对象,并且存储将随集合一起使用。如果要删除它,可以使用:
createObjects.prototype.removeObj = function(obj) {
var index = this.objects.indexOf(obj);
if (index != -1)
this.objects.splice(index, 1);
}
现在,您可以进行任何类型的功能以创建/删除不同的对象,它们将是具有不同属性的单独对象。
ps这种方法是拥有对象池的起点。但是,您必须使用不同的列表,或者至少为这些对象设置属性,说明是否使用了该对象。每次您要创建一个新对象时-检查是否有“自由”对象,如果存在,则将其返回。如果不是,请创建一个新的。
更新后,您实际上是在为所需的每个类创建新的工厂。每个工厂都包含一个对象,您可以通过在每个工厂上调用特定方法来修改该对象。尽管这可能对您有用,但这不是实际的工厂模式。为什么不在每次调用时都创建新对象(您不需要它们被单独的函数使用,对)?就像是:
createObjects.prototype.helloWorld = function(name) {
var result = {}; // CREATE brand new object
result.name = name;
result.greeting = "Hello " +name;
return result;
};
这样,您仍然可以将一个工厂与不同的对象一起使用:
var createFactory = require("./createFactory").objectFactory(); // create only ONCE
var helloWorldObject = createFactory.helloWorld("userOne");
// -> userOne
var byeWorldObject = createFactory.byeWorld("userTwo", 22);
// -> userTwo
helloWorldObj == byeWorldObj // -> false, different objects
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句