When is it a good idea to use factory methods within an object instead of a Factory class?
When is it a good idea to use factory methods within an object instead of a Factory class?
I like thinking about design pattens in terms of my classes being 'people,' and the patterns are the ways that the people talk to each other.
So, to me the factory pattern is like a hiring agency. You've got someone that will need a variable number of workers. This person may know some info they need in the people they hire, but that's it.
So, when they need a new employee, they call the hiring agency and tell them what they need. Now, to actually hire someone, you need to know a lot of stuff - benefits, eligibility verification, etc. But the person hiring doesn't need to know any of this - the hiring agency handles all of that.
In the same way, using a Factory allows the consumer to create new objects without having to know the details of how they're created, or what their dependencies are - they only have to give the information they actually want.
public interface IThingFactory
{
Thing GetThing(string theString);
}
public class ThingFactory : IThingFactory
{
public Thing GetThing(string theString)
{
return new Thing(theString, firstDependency, secondDependency);
}
}
So, now the consumer of the ThingFactory can get a Thing, without having to know about the dependencies of the Thing, except for the string data that comes from the consumer.
Factory methods should be considered as an alternative to constructors - mostly when constructors aren't expressive enough, ie.
class Foo{
public Foo(bool withBar);
}
is not as expressive as:
class Foo{
public static Foo withBar();
public static Foo withoutBar();
}
Factory classes are useful when you need a complicated process for constructing the object, when the construction need a dependency that you do not want for the actual class, when you need to construct different objects etc.
They're also useful when you need several "constructors" with the same parameter type but with different behavior.
It's really a matter of taste. Factory classes can be abstracted/interfaced away as necessary, whereas factory methods are lighter weight (and also tend to be testable, since they don't have a defined type, but they will require a well-known registration point, akin to a service locator but for locating factory methods).
Factory classes are useful for when the object type that they return has a private constructor, when different factory classes set different properties on the returning object, or when a specific factory type is coupled with its returning concrete type.
WCF uses ServiceHostFactory classes to retrieve ServiceHost objects in different situations. The standard ServiceHostFactory is used by IIS to retrieve ServiceHost instances for .svc files, but a WebScriptServiceHostFactory is used for services that return serializations to JavaScript clients. ADO.NET Data Services has its own special DataServiceHostFactory and ASP.NET has its ApplicationServicesHostFactory since its services have private constructors.
If you only have one class that's consuming the factory, then you can just use a factory method within that class.
GOF Definition :
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.
Generic example :
public abstract class Factory<T> {
public abstract T instantiate(Supplier<? extends T> supplier);
}
The concrete class
public class SupplierFactory<T> extends Factory<T> {
@Override
public T instantiate(Supplier<? extends T> supplier) {
return supplier.get();
}
}
The Implementation
public class Alpha implements BaseInterface {
@Override
public void doAction() {
System.out.println("The Alpha executed");
}
}
public class Beta implements BaseInterface {
@Override
public void doAction() {
System.out.println("The Beta executed");
}
}
public interface BaseInterface {
void doAction();
}
public class Main {
public static void main(String[] args) {
Factory<BaseInterface> secondFactory = new SupplierFactory<>();
secondFactory.instantiate(Beta::new).doAction();
secondFactory.instantiate(Alpha::new).doAction();
}
}
Brief advantages
I think it will depend of loose coupling degree that you want to bring to your code.
Factory method decouples things very well but factory class no.
In other words, it's easier to change things if you use factory method than if you use a simple factory (known as factory class).
Look into this example: https://connected2know.com/programming/java-factory-pattern/ . Now, imagine that you want to bring a new Animal. In Factory class you need to change the Factory but in the factory method, no, you only need to add a new subclass.
Factory classes are more heavyweight, but give you certain advantages. In cases when you need to build your objects from multiple, raw data sources they allow you to encapsulate only the building logic (and maybe the aggregation of the data) in one place. There it can be tested in abstract without being concerned with the object interface.
I have found this a useful pattern, particularly where I am unable to replace and inadequate ORM and want to efficiently instantiate many objects from DB table joins or stored procedures.
My short explanation will be that we use the factory pattern when we don't have enough information to create a concrete object. We either don't know the dependencies or we don't know the type of the object. And almost always we don't know them because this is information that comes at runtime.
Example: we know that we have to create a vehicle object but we don't know if it flies or it works on ground.
Imagine you have a different customers with different preferences. Someone need Volkswagen another one Audi and so on. One thing is common - it's a car.
To make our customer happy we need a factory. The factory only should know which car the customer want and will deliver such car to customer. If later we have some another car we can easily extend our car park and our factory.
Below you can see an example (ABAP):

Now we will create an instance of the factory and listening for the customers wishes.

We created three different cars with only one create( ) method.
Result:
Quite often is factory pattern very usefull if you want to make the logic more clean and the program more extensible.