Abstract factory design pattern in Java

By | August 20, 2023

The Abstract Factory design pattern in Java is a creational pattern that provides an interface (Abstract Factory) to create families of related objects without specifying their concrete classes. Concrete factory classes implement the interface to create specific object families. This pattern allows the client code to create objects without knowing their exact implementations, promoting flexibility and easy addition of new object families.

Abstract factory design pattern is similar to Factory design pattern; just the difference is that it is more like the factory to factories.

When to use Abstract factory design pattern?

  • Different Platforms
    • When we want our code to work on different platforms or systems (such as Windows or macOS), Abstract factory helps us create objects that match the configuration on each platform and run successfully without mixing them up.
    • Example: Consider we are making a game that runs on both Android and iOS. Using Abstract factory, we can create a factory for each platform that makes buttons and menus in the right style. In this way, we don’t accidentally use Android buttons on iOS.
  • Groups of Objects
    • If we need to create several related things that work together, like different styles of buttons and check-boxes, Abstract factory helps us ensure that they fit and work well together.
    • Example: Let’s say we are building a mobile app that lets users customize the theme of the mobile. Users can choose between different themes for their mobile, like “classic,” “modern,” and “funky.” Each theme includes a specific style for buttons and check-boxes, which can be easily implemented with the help of an abstract factory design pattern.
  • Adding New Stuff
    • If you plan to add new types of things in the future, like new types of buttons, using Abstract Factory makes it easier to slot them in without confusing existing parts.
    • Example: If we are building a control panel for a spaceship game and we have buttons for “Launch”, “Landing”, and “Emergency Stop”, we have used Abstract Factory to make these buttons. After some time, we decided to add more buttons for “Shield Activation” and “Communication”. Using Abstract Factory, we can add a new factory for each type of button. In this way, we can add new buttons without disturbing the old buttons and features.
  • Easy Changes
    • It helps keep your code neat when you want to change how objects are made or make changes to a group of objects. You can do this in one place.

Example

We will learn about Abstract factory design patterns with the help of the Clash of Clans game, which we used in our previous tutorial for Factory design patterns. In this tutorial, we extend that example to implement the Abstract factory design pattern.

Abstract factory
Fig 1- Abstract factory design pattern

In the above picture, the CharacterFactory is our abstract factory, and it is used to create families of related objects. i.e., ArcherCharacterFactory and WizardCharacterFactory; that’s why it is called the Factory of Factories.

Step-by-step implementation of the Abstract factory design pattern

Step 1- Create an interface

First, we need to create an interface Character, which represents the common properties of each character. It defines the methods that all character classes must implement. Concrete character classes Archer and Wizard will implement this interface and provide specific implementation of its methods.

Java
/**
 * Character - This interface will define the common
 * properties which must be implemented by all the
 * characters of game.i.e, Archer and Wizard
 * 
 * @author paulsofts
 */
public interface Character {
	
	void selectCharacter();
    void usePower();

}

Step 2- Create Archer and Wizard concrete classes

In this step, we will create the concrete character classes that implement the Character interface and provide the implementation of the character interface’s methods.

Archer.java
public class Archer implements Character {
	
	@Override
	public void selectCharacter() {
		System.out.println("Selected character: Archer");	
	}

	@Override
	public void usePower() {
		 System.out.println("Power: Deploy multiple arrows for area damage!");
	}

}

Similarly, we create the Wizard class and implement the Character interface.

Wizard.java
public class Wizard implements Character {
	
	@Override
	public void selectCharacter() {
		System.out.println("Selected character: Wizard");
	}

	@Override
	public void usePower() {
		System.out.println("Power: Cast a fireball that deals splash damage!");
	}

}

Step 3- Create CharacterFactory

This is the Abstract Factory. It’s an interface that declares the method createCharacter(), which concrete factories implement to create instances of characters. The CharacterFactory is responsible for creating families of related objects, different types of characters.

Java
/**
 * CharcterFactory - Abstract Factory
 * 
 * CharcterFactory - Concrete factories will 
 * implements this factory to create instances
 * of characters
 * 
 * @author paulsofts
 * */
public interface CharacterFactory {
	
	Character createCharacter();

}

Step 4- Create factories for different characters

In this step, we will create the factory classes for different characters available in our game, which will further implement the CharacterFactory and provide the implementation for the createCharacter() method.

ArcherCharacterFactory.java
public class ArcherCharacterFactory implements CharacterFactory {

	@Override
	public Character createCharacter() {
		return new Archer();
	}

}

In a similar way, we define the WizardCharacterFactory.

Java
public class WizardCharacterFactory implements CharacterFactory {

	@Override
	public Character createCharacter() {
		return new Wizard();
	}

}

Step 5- Client Code

Finally, we create our main class. i.e, ClashOfClans. Let’s understand how it’s working. For example, if the user wants to create an Archer game character, they will call ArcherCharacterFactory, which internally calls the CharacterFactory (AbstractFactory). This is known as Factory to Factories, and the CharacterFactory creates the object of the Archer game character. This Archer object is used to initialise the common properties of the Character interface.

Abstract factory - Factory to Factories
Fig 2- AbstractFactory: Factory to factories
Java
package com.paulsofts.abstractfactorypattern;

public class ClashOfClans {
	public static void main(String[] args) {
		
		CharacterFactory archerFactory = new ArcherCharacterFactory();
		CharacterFactory wizardFactory = new WizardCharacterFactory();
		
		Character archer = archerFactory.createCharacter();
		Character wizard = wizardFactory.createCharacter();
		
		archer.selectCharacter();
		archer.usePower();
		
		wizard.selectCharacter();
		wizard.usePower();
		
	}

}

Step 6- Test Application

Now, we run our ClashOfClains class and test our application.

Abstract factory - Output
Fig 3- Abstract Factory output

Difference between Factory and Abstract Factory design pattern

AspectFactory Design PatternAbstract Factory Pattern
IntentFactory pattern is used to create the single type objects. It specifies the sub-class to decide which concrete class will be instantiated.Abstract factory pattern provides an interface for creating the families of related objects without specifying their concrete classes.
AbstractionSimple and low level of abstraction.Complex and higher level of abstraction.
FlexibilityIt has less flexibility as it mainly concern with creating objects of single type.It offers more flexibility in adopting new type of product or changes.
ExampleCreating instances of various bank cards such as debit card, credit card etc.Creating different types of UI components such as buttons, checkboxes and other screen elements as they are families of related objects.

Leave a Reply

Your email address will not be published. Required fields are marked *