Design Patterns: Abstract Factory
Tags: beginners, programming, computerscience, architecture
Published: 2021-06-20 05:01:33

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8q5d4pm0hv1nzo7os7s4.png)

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

## Problem

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y7y5iy8wteauzs1mzxyj.png)

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. 

```java
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`.

```java
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.

```java
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`.

```java
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](https://refactoring.guru/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](https://www.amazon.com/Head-First-Design-Patterns-Brain-Friendly/dp/0596007124), which has fun and easy-to-read explanations.