如何编写符合“开放式封闭式原则”的工厂功能'

时间:2015-04-21 15:54:03

标签: javascript underscore.js

我一直在研究使用工厂函数作为JavaScript中构造函数的替代方法。我的大多数研究都源于Eric Elliot在其博客文章中提供的信息,例如:

http://ericleads.com/2012/09/stop-using-constructor-functions-in-javascript

虽然我同意这里所说的大部分内容,但我确实错过了构造函数的自动初始化方面,所以我想在我的工厂函数中实现类似的东西:

var myFactory = function (options) {
    var inst = _.create({
        initialize : function (options) {
            var allowedProps = ['name', 'type'];

            this.options = options;
            _.extend(this, _.pick(options, allowedProps));
        },

        test : function () {
            if(this.type === 'alpha') {
              return true;
            }

            return false;
        }
    })

    inst.initialize.call(inst, options);

    return inst;
};

var x = myFactory({ name : 'shiny', type : 'alpha' });
var y = myFactory({ name : 'happy', type : 'beta' });

1)这种行为本身只是重新引入构造函数带来的一些问题吗?

2)我通过使用'选项扩展实例来违反开放/封闭原则。在initialize方法中?它可以用于扩展(它可以用作原型),但我也可以通过“选项”修改原型本身。

我对这种模式感觉不好,觉得我应该对消费者进行初始化控制。它受到Backbone的扩展方法的启发,它依赖于构造函数。

进一步阅读:

https://tsherif.wordpress.com/2013/08/04/constructors-are-bad-for-javascript/

1 个答案:

答案 0 :(得分:1)

  

1)这种行为本身只是重新引入构造函数带来的一些问题吗?

不,它正在重新引入构造函数。只需将initialize换成constructor即可,您的结果几乎相同。只有非常单一的语法: - )

  

2)我通过使用'选项扩展实例来违反开放/封闭原则。在initialize方法中?

不,这篇文章指出构造函数如何打破开放/封闭原则是为了将它们与另一个工厂交换出来,你必须在代码中删除new(事实上你不这样做) 。但是如果你扩展你的课程,你就不必改变它的调用。

  

我对这种模式感觉不好,觉得我应该对消费者进行初始化控制。

好吧,如果你想这样做,只需删除初始化程序并让消费者执行extend

var x = _.extend(myFactory(), { name : 'shiny', type : 'alpha' });
var y = _.extend(myFactory(), { name : 'happy', type : 'beta' });