如何编写符合 'open closed principle' 的工厂函数

How to write factory functions that adhere to the 'open closed principle'

我一直在研究在 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) 在初始化方法中使用 'options' 扩展实例是否违反了 Open/Closed 原则?它是开放扩展的(它可以用作原型)但我也可以通过 'options' 修改原型本身。

我对这种模式有一种不好的感觉,觉得我应该将初始化的最终控制权交给消费者。它深受 Backbone 依赖于构造函数的扩展方法的启发。

进一步阅读:

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

1) Is this behavior itself just re-introducing some of the problems that come with constructors?

没有,虽然是重新引入构造函数。只需将 initialize 换成 constructor,您就会得到几乎相同的结果。只有非常单一的语法:-)

2) Am I violating the Open/Closed principle by extending the instance with 'options' within the initialize method?

不,这篇文章说明构造函数如何破坏 open/closed 原则的要点是,为了将它们换成不同的工厂,您必须删除整个代码中的 new(在事实上你不知道)。但是,如果您扩展 class,则不必更改其调用。

I've got a bad feeling about this pattern and feel like I should be giving ultimate control of initialization to the consumer.

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

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