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.