node.js 中的对象工厂模式
Object factory pattern in node.js
我在重构一段代码时遇到一个案例,要求我在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();
}
- 调用和创建新对象的方式是否符合对象工厂设计模式?
- 能否将 CASE 1 和 CASE 2 创建为空对象从 helloWorld 和 byeWorld 中删除(在上面的代码中标记为注释)?
- 工厂模式是否创建一个对象用于每个请求,或者工厂模式是否为每个请求创建新对象 "new"?
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);
}
现在您可以创建任何类型的函数来 create/delete 不同的对象,它们将是具有不同属性的独立对象。
p.s。
这种方法是拥有对象池的起点。但是你必须要么使用不同的列表,要么至少为那些对象设置属性,说明这个对象是否被使用。每次你想创建一个新的 - 检查是否有 "free" 对象,如果有 - return 它。如果没有 - 创建一个新的。
更新后,您实际上是在为每个 class 您想要的创建新工厂。每个工厂都包含 单个对象 ,您可以通过调用每个工厂的特定方法来修改这些对象。虽然这可能对您有用,但它不是真正的工厂模式。你为什么不在每次调用时创建新对象(你不需要它们被单独的函数使用,对吧)?类似于:
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
我在重构一段代码时遇到一个案例,要求我在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();
}
- 调用和创建新对象的方式是否符合对象工厂设计模式?
- 能否将 CASE 1 和 CASE 2 创建为空对象从 helloWorld 和 byeWorld 中删除(在上面的代码中标记为注释)?
- 工厂模式是否创建一个对象用于每个请求,或者工厂模式是否为每个请求创建新对象 "new"?
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);
}
现在您可以创建任何类型的函数来 create/delete 不同的对象,它们将是具有不同属性的独立对象。
p.s。 这种方法是拥有对象池的起点。但是你必须要么使用不同的列表,要么至少为那些对象设置属性,说明这个对象是否被使用。每次你想创建一个新的 - 检查是否有 "free" 对象,如果有 - return 它。如果没有 - 创建一个新的。
更新后,您实际上是在为每个 class 您想要的创建新工厂。每个工厂都包含 单个对象 ,您可以通过调用每个工厂的特定方法来修改这些对象。虽然这可能对您有用,但它不是真正的工厂模式。你为什么不在每次调用时创建新对象(你不需要它们被单独的函数使用,对吧)?类似于:
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