Abstract Factory?
For the longest time, this pattern was very confusing to me.
But through blood, sweat, and tears, I've finally cracked it down.
I don't want you to go through the same.
By the end of this article, you will:
- Understand the core concepts of Abstract Factory
- Recognize opportunities to use Abstract Factory
- Understand the pros and cons of Abstract Factory
Definition
Abstract factory is a creational design pattern that provides an interface to create families of classes without concrete implementations.
But Tamer, what do you mean by "families of classes"?
Well, imagine that you are creating a software for a furniture store. The store sells chairs, sofas, etc...
But there isn't only one type of chair there are multiple types of chairs.
You can call this a family of chairs, hence have different classes for each type of chair.
Problem
But now let's us imagine that we not only have a family of chairs, we have a family of tables, sofas, etc...
They also are a family for example:
- Victorian Furniture: Victorian Chair + Victorian Table + Victorian Sofa
- Modern Furniture: Modern Chair + Modern Table + Modern Sofa
So right now our problem is that we have to be able to create individual furniture objects so that they match other objects of the same family.
Solution
To begin, we would need to create an interface for each furniture, i.e chair, table, and sofa.
public interface Chair {
public void hasLegs();
public void sitOn();
}
// ... other interfaces for table and sofa
With this we can now create the specific objects such as VictorianChair
and ModernChair
.
public class VictorianChair implements Chair {
// code implementing victorian chair
}
public class ModernChair implements Chair {
// code implementhing modern chair
}
Next we would want to create families of products, for that we would create a factory. But to do that let's first create the interface the factory would use.
public interface FurnitureFactory {
public Chair createChair();
public Table createTable();
public Sofa createSofa();
}
With this, we can have, different factories for different types of furniture i.e VictorianFurnitureFactory
and ModernFurnitureFactory
.
public class VictorianFurnitureFactory implements FurnitureFactory {
@Override
public Chair createChair() {
return new VictorianChair();
}
@Override
public Table createTable() {
return new VictorianTable();
}
@Override
public Sofa createSofa() {
return new VictorianSofa();
}
}
// same thing for modern furniture factory
Things are much simpler now, for each new variant of furniture, we simply create a new class that implements the abstract factory in our case it's the FurnitureFactory
interface.
Now the client code only needs to accept a class that implements FurnitureFactory
and call it's respective methods. If you want a different variation you simply change the concrete factory class.
When to use the pattern?
Use the abstract factory pattern when you have families of objects, and you don't want them to concretely depend on each other. For example, I wouldn't want my VictorionChair
to be directly coupled with VictorianTable
or VictorianSofa
.
Pros & Cons
Pros
- Products are compatible with each other, because they all use the same interface.
- You avoid tight coupling between the concrete objects and client code.
- Single Responsibility Principle: you put the object creation all into one class. Hence making it easier to maintain.
- Open Closed Principle: to add new variants you don't have to change existing code.
Cons
- We added so many classes and interfaces, making the code more complicated.
Conclusion
Congratulations, you just learned the abstract factory. It's useful in many business domains, and you might just use it next time at work.
In this article, you learned:
- What the abstract factory is, and it's components.
- How to implement the abstract factory.
- When to recognize opportunities to use the abstract factory.
- Pros and cons of the abstract factory
Further Readings
If you want to learn more about the design patterns, I would recommend Diving into Design Patterns. It explains all 23 design patterns found in the GoF book, in a fun and engaging manner.
Another book that I recommend is Heads First Design Patterns: A Brain-Friendly Guide, which has fun and easy-to-read explanations.
Top comments (1)
'I wouldn't want my VictorionChair to be directly coupled with VictorianTable or VictorianSofa.' could you elaborate on this more (with some example if possible)?
also while I was reading the article you embedded the link of, I had a question. why is the return type of createButton inside suppose WinFactory declared as Button instead WinButton, although that function returns an instance of WinButton but why use the interface as return type instead of the class of that particular family? I mean when and why will WinFactory ever create a Button of some other family instead of WinButton?
BTW great article :)