My journey to understanding “Abstract Factories”

Edward Wang
Life’s Journey Through A Lens
3 min readApr 10, 2019
Me trying to understand ‘Abstract’

What is an abstract factory?

An abstract factory is a framework to create multiple typed objects that share similar functions. This allows you to simplify the client/usage side interaction when the end user doesn’t care what type and only wants it to accomplish that overlapping functions.

My journey to understanding them

It’s easier to give an example when trying to quantify the benefits, structure and future use case of something that is abstract.

Project Story

Let’s say you are designing a GPS/Music system for cars. There are multiple car manufacturers and each one requires a GPS setup method and supports different music providers.

The different manufacturers will be:

  • Honda — Spotify
  • Toyota — Pandora
  • Subaru — AppleMusic

Benefits

Instead of creating 3 separate classes to define the setup for these brands, you can have one main interface to define the methods they share. The benefit is that you can:

  • scale the # of brands supported with the framework
  • update the interface to remove/add on functionality for future use cases
  • you can cast the abstract car object into the specific brand to call its specialized methods

A way to keep clean code is to abstract away their redundancies to remove complexity and reduce code maintenance.

Structure

Car Class [abstract factory] — will be the interface that holds the methods the brands all share:

interface Car{
void setupGPS();
}
enum CarBrand{
HONDA, TOYOTA, SUBARU
}

Honda Class

class Honda implements Car{
@Override
public void setupGPS() {
System.out.println("Setup Honda GPS");
}
public void loginToSpotify(){
System.out.println("Logged into Spotify");
}
}

Toyota Class

class Toyota implements Car{
@Override
public void setupGPS() {
System.out.println("Setup Toyota GPS");
}
public void loginToPandora(){
System.out.println("Logged into Pandora");
}
}

Subaru Class

class Subaru implements Car{
@Override
public void setupGPS() {
System.out.println("Setup Subaru GPS");
}
public void loginToAppleMusic(){
System.out.println("Logged into AppleMusic");
}
}

Application Configurator Class — sets the car type based on the current system configuration and sets up the music system.

public class CarFactoryExample {
public static void main(String[] args){
//System Configuration
Configuration configuration = Configuration.getConfiguration();
//Configure car brand
CarBrand carBrand = CarBrand.valueOf(configuration.getType());
Car car = null;
switch (carBrand){
case HONDA:
car = new Honda();
((Honda) car).setupSpotify();
break;
case TOYOTA:
car = new Toyota();
((Toyota) car).setupPandora();
break;
case SUBARU:
car = new Subaru();
((Subaru) car).setupAppleMusic();
break;
}
Client app = new Client(car);
}
}

Client Class — Doesn’t care what brand the car is and only wants to focus on GPS setup.

class Client {
private Car car;
public Client(Car car){
this.car = car;
car.setupGPS();
car.connectToGPS();
}
}

Future Use Case

In the future, this car factory can be scalable to support more brands and we now have a framework to design them after. If there needs to be a specialized function for their music this can also be added and called when the system configuration sets the car brand. All of this can be done without the Client every having to worry about the different brands now and can focus on just calling the Car object to setup and connect the GPS while expecting the music system to be included.

In Conclusion

Here I’ve shown an example of an abstract factory. It is a framework that allows the client to abstract away the complexity of dealing with different types, when in reality they are all under the same family. You can not only extend support for more types but also call upon specialized methods within them as seen in the Application Configuration Class with the different music providers, making it even more versatile.

I hope this article has given you an idea on how abstract factories work.

--

--