Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question

closed as primarily opinion-based by gnat, Kilian Foth, GlenH7, MichaelT, Dan Pichelman Aug 14 at 20:32

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

10  
1  
What's a fabric class/method? –  Doval Aug 14 at 14:54

7 Answers 7

up vote 19 down vote accepted

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.

share|improve this answer
12  
IMO factories are least important thing for SOLID. You can do SOLID just fine without factories. –  Euphoric Aug 14 at 6:29
    
You forgot the "open/close" principle. With a factory it is easy not to break it –  BЈовић Aug 14 at 7:02
2  
One thing that never made sense to me is, if you use factories to make new objects then you have to make the factory in the first place. So what exactly does that get you? Is it assumed that someone else will give you the factory instead of you instantiating it on your own, or something else? This should be mentioned in the answer, otherwise it's unclear how factories actually solve any problem. –  Mehrdad Aug 14 at 10:14
1  
@BЈовић - Except that every time you add a new implementation, you now get to crack open the factory and modify it to account for the new implementation - explicitly violating OCP. –  Telastyn Aug 14 at 12:58
2  
Factories are useful in certain areas which the answer addressed. They are not appropriate to use everywhere. For example, using factories to create strings or lists would be taking it way too far. Even for UDTs they are not always necessary. The key is to use a factory when the exact implementation of an interface needs to be decoupled. –  Snowman Aug 14 at 14:43

Like whatsisname said, I believe this is case of cargo cult software design. Factories, especially the abstract kind are only usable, when your module creates multiple instances of a class and you want to give user of this module ability to specify what type to create. This is actually quite rare requirement, because most of the time, you just need one instance and you can just pass that directly instead of creating explicit factory.

The thing is, factories (and singletons) are extremely easy to implement and so people use them a lot even in places, where they are not necessary. So when programmer thinks "What design patterns should I use in this code?" the Factory is first that comes to his mind.

There is also case of YAGNI violation. Many factories are created "Maybe, one day, I will need to create those classes differently." in mind. Which is clear violation of YAGNI.

And factories become obsolete, when you introduce IoC framework, because IoC is kind of factory. And many IoC frameworks are able to create implementations of specific factories.

Also, there is no design pattern, that says to create huge static class with CreateXXX methods, which only call constructors. And it is especially not called a Factory (nor Abstract Factory).

share|improve this answer
    
I agree with most of your points except "IoC is kind of factory": IoC containers are not factories. They are a convenient method of achieving dependency injection. Yes, some are capable of constructing automatic factories, but they are not factories themselves and should not be treated as such. I'd also contend the YAGNI point. It is useful to be able to substitute a test double in your unit test. Refactoring everything to provide this after the fact is a pain in the ass. Plan ahead and don't fall for the "YAGNI" excuse –  Alex G Aug 14 at 11:29
1  
@AlexG - eh... in practice, pretty much all IoC containers work as factories. –  Telastyn Aug 14 at 12:59
3  
@AlexG Primary focus of IoC is to construct concrete objects for passing into other objects based on configuration/convention. This is same thing as using factory. And you don't need factory to be able to create a mock for test. You just instantiate and pass the mock directly. Like I said in first paragraph. Factories are only useful when you want to pass creation of an instance to user of the module, which calls the factory. –  Euphoric Aug 14 at 13:41
1  
There's a distinction to be made. The factory pattern is used by a consumer to create entities during the runtime of a program. An IoC container is used to create the object graph of the program during start-up. You can do this by hand, the container is just a convenience. The consumer of a factory should not be aware of the IoC container. –  Alex G Aug 14 at 14:16
1  
Re: "And you don't need factory to be able to create a mock for test. You just instantiate and pass the mock directly" - again, different circumstances. You use a factory to request an instance - the consumer is in control of this interaction. Supplying an instance through the constructor or a method doesn't work, it's a different scenario. –  Alex G Aug 14 at 14:26

Constructors are fine when they contain short, simple code.

When initialization becomes more than assigning a few variables to the fields, a factory makes sense. Here are some of the benefits:

  • Long, complicated code makes more sense in a dedicated class (a factory). If the same code is put in a constructor which calls a bunch of static methods, this will pollute the main class.

  • In some languages and some cases, throwing exceptions in constructors is a really bad idea, since it can introduce bugs.

  • When you invoke a constructor, you, the caller, needs to know the exact type of the instance you want to create. This is not always the case (as a Feeder, I just need to construct the Animal in order to feed it; I don't care if it's a Dog or a Cat).

share|improve this answer
2  
The choices are not only "factory" or "constructor." A Feeder might use neither, and instead call it's Kennel object's getHungryAnimal method. –  DougM Aug 14 at 13:13
1  
+1 I find that adhering to a rule of absolutely no logic in a constructor is not a bad idea. A constructor should only be used for setting the initial state of the object by assigning its arguments values to instance variables. If anything more complicated is needed, at the very least make a factory (class) method to build the instance. –  KaptajnKold Aug 14 at 15:07

If you work with interfaces then you can remain independent of the actual implementation. A factory can be configured (via properties, parameters or some other method) to instantiate one of a number of different implementations.

One simple example: you want to communicate with a device but you don't know if it will be via Ethernet, COM or USB. You define one interface and 3 implementations. At runtime you could then select which method you want and the factory will give you the appropriate implementation.

Use it often...

share|improve this answer
3  
I would add that it is great to use when there are multiple implementations of an interface and the calling code does not or should not know which one to pick. But when a factory method is simply a static wrapper around a single constructor as in the question, that is the anti-pattern. There has to be multiple implementations from which to pick or the factory is getting in the way and adding unnecessary complexity. –  Snowman Aug 14 at 14:46

The Factory pattern vogue stems from an almost-dogmatic belief among coders in "C-style" languages (C/C++, C#, Java) that use of the "new" keyword is bad, and should be avoided at all costs (or at least centralized). This, in turn, comes from an ultra-strict interpretation of the Single Responsibility Principle (the "S" of SOLID), and also of the Dependency Inversion Principle (the "D"). Simply stated, the SRP says that ideally a code object should have one "reason to change", and one only; that "reason to change" is the central purpose of that object, its "responsibility" in the codebase, and anything else that requires a change to code should not require opening up that class file. The DIP is even simpler; a code object should never be dependent upon another concrete object, but instead on an abstraction.

Case in point, by using "new" and a public constructor, you are coupling the calling code to a specific construction method of a specific concrete class. Your code now has to know that a class MyFooObject exists, and has a constructor that takes a string and an int. If that constructor ever needs more information, all usages of the constructor have to be updated to pass in that information including the one you're writing now, and therefore they are required to have something valid to pass in, and so they must either have it or be changed to get it (adding more responsibilities to the consuming objects). In addition, if MyFooObject is ever replaced in the codebase by BetterFooObject, all usages of the old class have to change to construct the new object instead of the old one.

So, instead, all consumers of MyFooObject should be directly dependent on "IFooObject", which defines the behavior of implementing classes including MyFooObject. Now, consumers of IFooObjects can't just construct an IFooObject (without having the knowledge that a particular concrete class is an IFooObject, which they don't need), so instead they must be given an instance of an IFooObject-implementing class from outside, by another object that has the responsibility of knowing how to create the correct IFooObject for the circumstance, which in our parlance is usually known as a Factory.

Now, here's where theory meets reality; an object can never be closed to all types of change all the time. Case in point, IFooObject is now an additional code object in the codebase, which must change whenever the interface required by consumers or implementations of IFooObjects change. That introduces a new level of complexity involved in changing the way objects interact with each other across this abstraction. In addition, consumers will still have to change, and more deeply, if the interface itself is replaced by a new one.

A good coder knows how to balance YAGNI ("You Ain't Gonna Need It") with SOLID, by analyzing the design and finding places that are very likely to have to change in a particular way, and refactoring them to be more tolerant of that type of change, because in that case "you are gonna need it".

share|improve this answer
2  
Love this answer, in special after reading all other ones. I can add almost all (good) new coders are too much dogmatic about principles by the simple fact they really want to be good but don't learned yet the value of keeping things simple and don't overkill. –  jean Aug 14 at 17:48

It's a symptom of a limitation in Java/C#'s module systems.

In principle, there's no reason you shouldn't be able to swap out one implementation of a class for another with the same constructor and method signatures. There are languages that allow this. However, Java and C# insist that every class have a unique identifier (the fully qualified name) and the client code ends up with a hard-coded dependency on it.

You can sort of get around this by fiddling with the file system and compiler options so that com.example.Foo maps to a different file, but this is surprising and unintuitive. Even if you do so, your code is still tied to only one implementation of the class. I.e. If you write a class Foo that depends on a class MySet, you can choose an implementation of MySet at compile time but you still can't instantiate Foos using two different implementations of MySet.

This unfortunate design decision forces people to use interfaces unnecessarily to future-proof their code against the possibility that they'll later need a different implementation of something, or to facilitate unit testing. This isn't always feasible; if you have any methods that look at the private fields of two instances of the class, won't be able to implement them in an interface. That's why, for example, you don't see union in Java's Set interface. Still, outside of numeric types and collections, binary methods aren't common, so you can usually get away with it.

Of course, if you call new Foo(...) you still have a dependency on the class, so you need a factory if you want a class to be able to instantiate an interface directly. However, it's usually a better idea to accept the instance in the constructor and let someone else decide which implementation to use.

It's up to you to decide if it's worth bloating your codebase with interfaces and factories. On the one hand, if the class in question is internal to your codebase, refactoring the code so that it uses a different class or an interface in the future is trivial; you could invoke YAGNI and refactor later if the situation arises. But if the class is part of the public API of a library you've published, you don't have the option of fixing the client code. If you don't use an interface and later need multiple implementations, you'll be stuck between a rock and a hard place.

share|improve this answer
2  
I wish Java and derivatives like .NET had a special syntax for a class creating instances of itself, and otherwise had new simply be syntactic sugar for calling a specially-named static method (which would be auto-generated if a type had a "public constructor" but didn't explicitly include the method). IMHO, if code just wants a boring default thing that implements List, it should be possible for the interface to give it one without the client having to know of any particular implementation (e.g. ArrayList). –  supercat Aug 14 at 20:39

In my opinion, they're just using the Simple Factory, which is not a proper design pattern and should not be confused with the Abstract Factory or the Factory Method.

And since they have created a "huge fabric class with thousands of CreateXXX static methods", that sounds to an anti-pattern (a God class maybe?).

I think the Simple Factory and static creator methods (which doesn't require an external class), can be useful in some cases. For example, when the construction of an object requires various steps like instancing other objects (e.g. favoring composition).

I wouldn't call even call that a Factory, but just a bunch of methods encapsulated in some random class with the suffix "Factory".

share|improve this answer
1  
Simple Factory has its place. Imagine an entity takes two constructor parameters, int x and IFooService fooService. You don't want to be passing around fooService everywhere, so you create a factory with a method Create(int x) and inject the service inside the factory. –  Alex G Aug 14 at 14:29
2  
@AlexG And then, you have to pass around IFactory everywhere instead of IFooService. –  Euphoric Aug 14 at 15:10
1  
I agree with Euphoric; in my experience, objects that get injected into a graph from the top tend to be of a type that all lower-level objects need, and so passing IFooServices around is no big deal. Replacing one abstraction with another doesn't accomplish anything but further obfuscating the codebase. –  KeithS Aug 14 at 16:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.