Factory Pattern - CreateInstance static or not?

18,437

Solution 1

Static method doesn't violate the pattern but it goes against many other object oriented practices (inversion of control + dependency injection as one example) so using instances is better.

Edit:

I just got some badge for this answer but when I read it I could not believe my eyes. It is wrong when we strictly speak about GoF Factory method pattern and it deserves some correcting.

You can have static CreateInstance method for creating instance of a type - there is nothing wrong about that - people often call it factory method but that is not what is called Factory Method pattern. Once you start putting logic into this method to create instances of different types depending on some condition you may be actually in need of Factory Method pattern described by GoF.

The point of GoF Factory method pattern is to replace conditional logic inside CreateInstance with inheritance and polymorphism and thus it cannot be static. Factory method is an instance method - moreover it is virtual. Your base type has usually abstract CreateInstance and conditional logic is replaced by inheritance tree where each subtype overrides CreateInstance and creates just specific product for that subtype.

Solution 2

I'm very hesitant to categorize "instance versus static" as a matter of taste. This sort of implies that it's aesthetic like a favorite color or, more appropos, camelCase versus PascalCase.

Instance versus static is more a question of tradeoffs. With instance members of any kind, you get all of the benefits of polymorphism, since you can implement interfaces and inherit from other classes when you have instances and instance members. With statics, you do not get these benefits. Generally, static versus instance is a tradeoff for up-front simplicity versus downstream simplicity. Statics are easy because they are globally accessible and you don't have to consider things like "when should this be instantiated and by whom?" You don't have to pass them around with accessors/mutators or constructors, and your API looks cleaner. This makes up front reasoning easier. But, it makes maintenance and future implementations harder.

If you have a static method -- say a factory method in your case -- and you later want it to behave differently in certain situations, you're kind of hosed. You have to make a second method and copy and paste the functionality minus whatever you want to change, and then have clients figure it out. Or, worse, you expose a global variable and have clients set this before and after using your method, with the global telling the method how to behave.

If you had gone the instance route up front, this would be easy. You'd just inherit and override your initial factory method and provide the derived classes where you need the new functionality. You're not placing additional burden on client code and you're making almost no modifications to existing classes (open/closed principle).

My advice would be to do future you and/or other maintainers a favor and use the instance implementation. It's not a matter of what the Gang of Four or anyone else want or prefer - it's a matter of your own sanity in the face of code rot.

Solution 3

If its an abstract factory then instance level is normal. And instance level functionality tends to be easier to mock and unit test than static level

Share:
18,437
dknaack
Author by

dknaack

Updated on June 15, 2022

Comments

  • dknaack
    dknaack almost 2 years

    This is about the Factory Pattern. I am a little confused.

    I saw implementations where the createInstance() method is static and some implementations that are non-static.

    Some say it's depending on "style" or "taste" and some say it does not. Wikipedia says that it should be non-static, and http://www.dofactory.com/Patterns/PatternFactory.aspx also says that it should be non-static, according to the Gang of Four.

    My question is: does it depend on style & taste or does it violate the Factory Pattern if it's implemented the static way? What's right?

  • corsiKa
    corsiKa over 12 years
    Couldn't you use a static injection, like static void setFactory(Factory fact)?
  • dknaack
    dknaack over 12 years
    Ok, thank you. I don't have to change anything. Your argument fits my thinking of oop. Thank you for confirming this.
  • Yorro
    Yorro over 10 years
    @corsiKlauseHoHoHo - Doing that means that you have to remember to use setFactory() everytime you need to use the factory. Unlike a instance class, you are required to use the constructor, alleviating you the burden of having to remember the required methods.
  • corsiKa
    corsiKa over 10 years
    @Yorro no, you would only need to set the factory once on system startup or on demand due to a user-requested configuration change. You can still have it injected dynamically based on configuration settings. If I were invoking a setFactory() every time, I would imagine I'd instead be using builders instead of factories, and running them through a static method would involve trickery like threadlocal on the inside... I'd rather have a factory of builders in that case...