I\'ve seen the history of several ?#/Java class library projects on GitHub and C
ID: 644834 • Letter: I
Question
I've seen the history of several ?#/Java class library projects on GitHub and CodePlex, and it seems like a trend.
Why do people nowadays use factory classes so often for almost everything? I.e. We have pretty good library, where objects are created the old-fashioned way - by invoking public constructors of classes.. Now, in the last commits the authors quickly changed all of the public constructors of thousands of classes to internal, and also created one huge factory class with thousands of CreateXXX static methods that just return new objects by calling the internal constructors of the classes. The external project API is broken, well done...
Why? What is the point of such "refactoring"? What is a great benefits from replacing calls to all public class constructors with static factory method calls? Is having public constructors something like "bad practice" now?
Explanation / Answer
Factory classes are often implemented because they allow the project to follow the SOLID principles more closely. In particular, the interface segregation and dependency inversion principles.
Factories and interfaces allow for a lot more long term flexibility. It allows for a more decoupled - and therefore more testable - design. Here is a non-exhaustive list of why you might go down this path:
It allows you to introduce an IoC container easily
It makes your code more testable as you can mock interfaces
It gives you a lot more flexibility when it comes time to change the application (i.e. you can create new implementations without changing the dependent code)
Consider this situation.
Assembly A (-> means depends upon):
Class A -> Class B
Class A -> Class C
Class B -> Class D
I want to move Class B to Assembly B, which is dependent on Assembly A. With these concrete dependencies I have to move most of my entire class hierarchy across. If I use interfaces, I can avoid much of the pain.
Assembly A:
Class A -> Interface IB
Class A -> Interface IC
Class B -> Interface IB
Class C -> Interface IC
Class B -> Interface ID
Class D -> Interface ID
I can now move class B across to assembly B with no pain whatsoever. It still depends on the interfaces in assembly A.
Using an IoC container to resolve your dependencies allows you even more flexibility. There is no need to update each call to the constructor whenever you change the dependencies of the class.
Following the interface segregation principle and the dependency inversion principle allows us to build highly flexible, decoupled applications. Once you have worked on one of these types of applications you will never again want to go back to using the newkeyword.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.