我在重构一段需要我在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"}
这种方法是否可以消除问题?
答案 0 :(得分:2)
很高兴知道,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);
}
现在你可以创建任何类型的函数来创建/删除不同的对象,它们将是具有不同属性的独立对象。
P.S。 这种方法是拥有对象池的起点。但是,您必须使用不同的列表或至少为这些对象设置属性,说明是否使用了此对象。每次你想要创建一个新的 - 检查是否有&#34;免费&#34;对象,如果是 - 返回它。如果不是 - 创建新的。
更新后,您实际上是为所需的每个课程创建新工厂。每个工厂都包含单个对象,您可以通过调用每个工厂的特定方法来修改它们。虽然这可能对您有用,但它不是实际的工厂模式。为什么不在每次通话时创建新对象(你不会需要它们被不同的功能使用,对吧)?类似的东西:
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