node.js中的对象工厂模式

时间:2015-09-15 06:13:45

标签: javascript node.js design-patterns factory

我在重构一段需要我在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();
}
  1. 是按照对象工厂设计模式调用和创建新对象的方法吗?
  2. 可以从helloWorld和byeWorld中删除CASE 1和CASE 2作为空对象吗(在上面的代码中标记为注释)?
  3. 工厂模式是否创建了与每个​​请求一起使用的单个对象?工厂模式是否为每个请求创建新对象为“new”?
  4. 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"}
    

    这种方法是否可以消除问题?

1 个答案:

答案 0 :(得分:2)

很高兴知道,Factory模式实际上创建了对象。它不习惯以任何方式重复使用它们。

如果要重复使用它们,则应使用所谓的object pool

现在,您的代码中存在一些问题。一切都从这里开始:

exports.createObjects = function(){
    return new createObjects();
}

因此,第一次使用require("./createFactory").createObjects()时,将执行该函数并创建新工厂。现在,每次使用该工厂时,都会开始使用同一个对象 - this.localObject。这意味着您不会收集任何项目,而不是每次使用helloWorldbyeWorld时更改的项目。

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