Christmas Gifts

Design Patterns in Java: Abstract Factory Pattern

This blog post describes how to use the abstract factory design pattern.

This post is part of the Design Patterns in Java Series. Check out the full list of covered patterns there.

Before you read on, I highly recommend you first read my previous post on the factory method pattern. The abstract factory pattern is essentially a generalisation of the factory method, so it makes sense to understand the simpler case first.

Why Should You Use the Abstract Factory Design Pattern?

The abstract factory is used when we need to create families of products without having to depend on concrete classes.

Essentially, you would use this pattern to package a bundle of related products.

You would then create each product using a factory method.

The headline photo of this article is supposed to suggest the idea of packaging things together.

What is an Abstract Factory?

Here’s the definition from the Head First Design Patterns book:

Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

In other words, the abstract factory creates a package of multiple products, whereas the factory method creates one product.

In this way, I like to think of the abstract factory as a kind of generalisation of the factory method pattern.

Furthermore, we’re controlling the package creation step so we ensure that clients get packages with matched products. In the absence of the pattern, clients might put together products that don’t make sense to bundle together.

You’ll better understand the pattern with the class diagram below. This builds nicely on the diagram from the factory method pattern.

Let’s go back to our computer manufacturing business. In the factory method example, we were only building laptops, namely normal laptops and gaming laptops. Let’s also assume that we are currently operating in the US.

Since our business is going well, we want to extend our product range to computer servers. Similarly, we will offer a normal server and a more powerful gaming server as products.

As we would also like to cut manufacturing costs, we plan on opening a new company branch in Poland. We want the Poland branch to take care of building the gaming laptops and gaming servers as these are more expensive to manufacture.

Therefore, we have two groups of products, namely the normal range of computers and the gaming range. The former is built in the US, the latter is built in Poland.

Coming back to the definition of the abstract factory, the related products in this case would be the laptops and the servers.

Abstract Factory Class Diagram

Abstract Factory Class Diagram

In this diagram, ComputerFactory is our interface for creating our bundle of related products. The two concrete factory implementations are USComputerFactory and PolandComputerFactory.

The USComputerFactory creates packages of NormalLaptops and NormalServers, while the PolandComputerFactory creates packages of GamingLaptops and GamingServers.

Pros

  • similar to the factory method, the pattern avoids tight coupling between the client and object creation.
  • allows bundling related product objects and promises compatibility between them.

Cons

  • if the abstract factory interface changes (i.e. ComputerFactory in the example above), then all factories would need to be updated.
  • increased code complexity due to the new classes.

Abstract Factory vs Factory Method

Congratulations! You’re now familiar with both factory patterns. Let’s put them in contrast.

Well, we’ve already established that both of these patterns create objects.

Additionally, both patterns decouple client code from concrete types as clients are only concerned with the abstract types.

The difference is that on one hand, the factory method creates objects via inheritance—since creation is delegated to subclasses. On the other hand, the abstract factory relies on object composition to create a bundle of objects. Each object is created via its own factory method.

How Can You Implement the Abstract Factory Pattern?

Let’s implement in Java the class design from the previous section.

Abstract Factory Pattern Java Code Example

The Laptop and Server interfaces would be:


The classes implementing the Laptop interface are:


The classes implementing the Server interface are:


Next, the ComputerFactory interface is the actual abstract factory that we’re trying to illustrate.

The USComputerFactory is a concrete implementation of the ComputerFactory interface and returns a package of a NormalLaptop object and a NormalServer object:

The PolandComputerFactory is another concrete implementation of the ComputerFactory interface and returns a package of a GamingLaptop object and a GamingServer object:

Lastly, the client code can be:

The output is then:

Summary

In conclusion, the three main key points are:

  1. Abstract factory creates families of related products.

  2. The pattern decouples client code from concrete products.

  3. Abstract factory pattern ensures compatibility between packaged products.

About the Author Dragos Stanciu

follow me on:

Subscribe

Like this article? Stay updated by subscribing to my weekly newsletter:

Leave a Comment: