DEV Community

Cover image for Design Patterns: Abstract Factory
Tamerlan Gudabayev
Tamerlan Gudabayev

Posted on • Edited on

Design Patterns: Abstract Factory

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.

Alt Text

You can call this a family of chairs, hence have different classes for each type of chair.

Problem

Alt Text

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
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
zyabxwcd profile image
Akash • Edited

'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 :)