Does the Factory Method pattern violate the Open/Closed principle?
Asked Answered
L

3

12

Does the Factory Method pattern (not to be confused with the Factory or Abstract Factory patterns) violate the Open/Closed principle?

Update: To clarify, I'm referring to the scenario where a concrete class has static factory methods on it. For example (this is from the Wikipedia page on FMP):

class Complex 
{
    public static Complex fromCartesian(double real, double imag) {
        return new Complex(real, imag);
    }

    public static Complex fromPolar(double modulus, double angle) {
        return new Complex(modulus * cos(angle), modulus * sin(angle));
    }

    private Complex(double a, double b) {
       //...
    }
}

Doesn't the private constructor prevent the class from being subclassed, i.e. extended?

Wouldn't the class have to be modified to support new factory methods? For example, if the class initially only had fromCartesian and later fromPolar was needed, didn't the class have to be modified to support this?

Don't both of these violate Open/Closed?

Loudmouthed answered 4/3, 2010 at 17:4 Comment(8)
I'd like to know what you think of this before I answer. Your answer will make me feel you are looking for the answer. Otherwise it is like you are outsourcing your work to SO.Laryngeal
Sorry, was planning to add a comment, but got sidetracked by work. :) I'm thinking it does violate it. Please correct me if I'm wrong, but FMP dictates a private constructor, and a private constructor prohibits extension. Also, wouldn't the class have to be modified to support alternate implementations? I'm thinking of the situation where a class has static factory methods. Maybe this is only one flavor of FMP?Loudmouthed
If it a child class then you can overide the method or use super() (assuming Java). You're better off not having static methods and have one single method that takes parameters as to which one to choose using a switch statement or by reading in a provided configuration file.Albumin
Wouldn't the switch statement still require modifying the class? What about the issue of the private constructor preventing extension?Loudmouthed
The Wikipedia code you cite isn't really the classical Factory Method pattern. It's similar, but in my opinion, it's not the same thing. You wouldn't use code like that in a situation that called for a Factory Method.Mascarenas
Ok, so the core problem may be that what I thought was a flavor of Factory Method is really not. Would you agree that what is presented above does violate the Open/Closed principle?Loudmouthed
That specific code doesn't really because things like numbers are generally a special case and the ways of creating them are not something that your requirements are going to call for being configurable. But some other class (containing business logic that could change) that had a private constructor and static factory methods? Yes.Mascarenas
Differences between Abstract Factory Pattern and Factory Method The example here is neither.Linetta
A
6

No, it doesn't violate the Open/Closed principle at all.

Open/Closed means you can modify the way a system works without modifying the code that already exists. You can extend the code and use it in different ways, but the old code is still in tact and doesn't need to be re-tested.

The Factory Method pattern will create a different type of object based on specified parameters. Factory Method actually works well with the Open/Closed principle if done correctly. However, if you create a new class and then want the Factory Method to create a new object of that type you would have to change the Factory Method.

Although, if you had some kind of configuration file or something of that sort that is read in by the Factory Method then you wouldn't have to change the Factory Method ... just the config file that then dictates what object will be created by the Factory Method.

Albumin answered 4/3, 2010 at 17:11 Comment(0)
T
7

The Factory pattern isn't inherently a violator of OCP.

It depends on how you take the behavior of Complex further.

If Complex is required to support the production of new types of Complex object, and you choose to modify Complex by adding new fromX methods are added to support them, then this means that Complex becomes a violator of the OCP because Complex must be re-opened for modification:

class Complex 
{
    public static Complex fromCartesian(double real, double imag) {
        return new Complex(real, imag);
    }

    public static Complex fromPolar(double modulus, double angle) {
        return new Complex(modulus * cos(angle), modulus * sin(angle));
    }

    //class opened for modification
    public static Complex fromOtherMeans(String x , String y) {
        return new Complex(x, y);
    }
}

You could push this problem down into a text file or properties file of some sort in order to absolve yourself of having to change the java class, but it doesn't prevent you from having to write extra logic in this area of the solution in order to support new types of Complex.

Depending on the usage of Complex in your design (how are the various types different? How are you using them?), there are some alternative options which may apply well.

One such OCP friendly alternative is to subclass Complex to provide the additional factory methods. A subclass is the simplest illustration of how Complex is extended but not modified.

Another OCP friendly alternative to altering Complex in this case is the Decorator pattern. Continuously decorating Complex with the ability to create new variants of Complex respects the OCP because Complex is not modified but is extended by wrapping it with new functionality.

A third alternative might be to alter the structure of Complex so that its calculation is supplied by composition. This would open up to you the opportunity to use the Strategy pattern to diferentiate between the different behaviours of Complex.

The thing about the Factory pattern is that it helps context code respect OCP. One might employ one of the techniques above in order to stay on the right side of the OCP with their Factory class, but your colleagues are likely to take one look at the object graph, question the wisdom of having an object graph over a single Factory, and simplify it back into one Factory, which brings you back to to the first example.

In such cases, rather than trying to bend your implementation of the Factory pattern to respect the SOLID principles, consider why you're using it at all.

Tactician answered 24/6, 2014 at 9:3 Comment(0)
A
6

No, it doesn't violate the Open/Closed principle at all.

Open/Closed means you can modify the way a system works without modifying the code that already exists. You can extend the code and use it in different ways, but the old code is still in tact and doesn't need to be re-tested.

The Factory Method pattern will create a different type of object based on specified parameters. Factory Method actually works well with the Open/Closed principle if done correctly. However, if you create a new class and then want the Factory Method to create a new object of that type you would have to change the Factory Method.

Although, if you had some kind of configuration file or something of that sort that is read in by the Factory Method then you wouldn't have to change the Factory Method ... just the config file that then dictates what object will be created by the Factory Method.

Albumin answered 4/3, 2010 at 17:11 Comment(0)
M
2

Nope. From your Wikipedia link:

software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

Overriding the factory method is extension. You're creating a new class. You don't change the existing class. You have to substitute (via configuration of your IoC container hopefully) the subclass for the original.

Mascarenas answered 4/3, 2010 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.