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

I was looking into using factory functions as an alternative to constructors in JavaScript. Most of my research comes from information provided by Eric Elliot in his blogs, for example:

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

While I agree with most of what has been said here, I am missing the automatic aspect of initializing constructors, so I wanted to implement something like this in my factory function:

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) Is this behavior just a re-introduction of some constructor-related problems?

2) Am I violating the Open / Closed principle by extending an instance with "parameters" in the initialize method? It is open to extension (it can be used as a prototype), but I can also modify the prototype itself with "options".

I have a bad idea of ​​this pattern and feel that I should give the ultimate initialization control to the consumer. It is heavily inspired by the Backbone extension method, which relies on constructors.

Further reading:

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

+3


source to share


1 answer


1) Is this behavior just a re-introduction of some constructor-related problems?

No, although it reintroduces constructors. Just replace initialize

with constructor

and you get pretty much the same result. Only with very uniiomatic syntax :-)

2) Am I violating the Open / Closed principle by extending an instance with "parameters" in the initialization method?

No, the point is that the article shows how constructors violate the open / closed principle, which is that in order to replace them with another factory, you had to delete new

all over your code (which you don't actually use), but if you extend your class, you don't have to change its calls.



I have a bad idea of ​​this pattern and feel that I must give the ultimate initialization control to the consumer.

Well, if you want to do this, just remove the initializer and let the consumer do extend

:

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

      

+1


source







All Articles