Tutorials  /  JavaScript

Design Patterns in Java: The Abstract Factory Pattern

Ccentron Redaktion · June 2024 ·4 min read ·JavaScript, Tutorial

Learn all about the Abstract Factory Design Pattern in Java, a powerful method for structuring and creating classes. Discover the differences from conventional Factory Patterns and see practical examples of applying this design pattern. Enhance your Java programming skills and make your code architecture more efficient.

Abstract Factory

If you're familiar with the Factory Design Pattern in Java, you'll notice that we have a single Factory class. This Factory class returns different subclasses based on the provided input and uses if-else or switch statements to achieve this. In the Abstract Factory Pattern, we eliminate the if-else blocks and have a Factory class for each subclass. Then, there is an abstract Factory class that returns the subclass based on the input Factory class. At first, it may seem confusing, but once you see the implementation, it's really easy to understand and grasp the slight difference between Factory and Abstract Factory Patterns. As in our Factory Pattern post, we use the same superclass and subclass.

Superclass and Subclass for the Abstract Factory Design Pattern

Computer.java

Go

package com.journaldev.design.model;

public abstract class Computer {

    public abstract String getRAM();
    public abstract String getHDD();
    public abstract String getCPU();

    @Override
    public String toString(){
        return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
    }
}

PC.java

Go

package com.journaldev.design.model;

public class PC extends Computer {

    private String ram;
    private String hdd;
    private String cpu;

    public PC(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public String getRAM() {
        return this.ram;
    }

    @Override
    public String getHDD() {
        return this.hdd;
    }

    @Override
    public String getCPU() {
        return this.cpu;
    }

}

Server.java

Go

package com.journaldev.design.model;

public class Server extends Computer {

    private String ram;
    private String hdd;
    private String cpu;

    public Server(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public String getRAM() {
        return this.ram;
    }

    @Override
    public String getHDD() {
        return this.hdd;
    }

    @Override
    public String getCPU() {
        return this.cpu;
    }

}

Factory Class for Each Subclass

First, we need to create an abstract Factory interface or class.

ComputerAbstractFactory.java

Go

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public interface ComputerAbstractFactory {

    public Computer createComputer();

}

Note that the createComputer() method returns an instance of the Computer superclass. Now, our factory classes will implement this interface and return their respective subclass.

PCFactory.java

Go

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;

public class PCFactory implements ComputerAbstractFactory {

    private String ram;
    private String hdd;
    private String cpu;

    public PCFactory(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }
    @Override
    public Computer createComputer() {
        return new PC(ram,hdd,cpu);
    }

}

Similarly, we will have a factory class for the Server subclass.

ServerFactory.java

Go

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;
import com.journaldev.design.model.Server;

public class ServerFactory implements ComputerAbstractFactory {

    private String ram;
    private String hdd;
    private String cpu;

    public ServerFactory(String ram, String hdd, String cpu){
        this.ram=ram;
        this.hdd=hdd;
        this.cpu=cpu;
    }

    @Override
    public Computer createComputer() {
        return new Server(ram,hdd,cpu);
    }

}

Consumer Class

Now, we will create a consumer class that serves as the entry point for client classes to create a subclass.

ComputerFactory.java

Go

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public class ComputerFactory {

    public static Computer getComputer(ComputerAbstractFactory factory){
        return factory.createComputer();
    }
}

Note that it's a simple class, and the getComputer method accepts an argument of type ComputerAbstractFactory and returns a Computer object. At this point, the implementation should become clear. Let's write a simple test method and see how the Abstract Factory is used to obtain an instance of the subclass.

TestDesignPatterns.java

Go

package com.journaldev.design.test;

import com.journaldev.design.abstractfactory.PCFactory;
import com.journaldev.design.abstractfactory.ServerFactory;
import com.journaldev.design.model.Computer;

public class TestDesignPatterns {

    public static void main(String[] args) {
        testAbstractFactory();
    }

    private static void testAbstractFactory() {
        Computer pc = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));
        Computer server = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new ServerFactory("16 GB","1 TB","2.9 GHz"));
        System.out.println("AbstractFactory PC Config::"+pc);
        System.out.println("AbstractFactory Server Config::"+server);
    }
}

The output of the above program will be:

Code

AbstractFactory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
AbstractFactory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
VM

Matching infrastructure at centron

Node applications need somewhere to run: ccloud³ VMs with full root access from €3.12 per month – or as a managed server if you would rather not run it yourself. Rent a cloud server →

Advantages of the Abstract Factory Design Pattern

  • The Abstract Factory Design Pattern provides an approach to coding for the interface rather than the implementation.
  • The Abstract Factory Pattern is a "factory of factories" and can easily be extended to accommodate more products.
Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie JavaScript
Teilen
Noch offene Fragen?

Our team will help you with your specific setup - in German or English, by people who run the platform themselves.

War dieses Tutorial hilfreich?

Your answer is stored anonymously and helps us improve our tutorials.

Kommentare

No comments yet - be the first to ask a question about this tutorial.

Sign in to comment

Comments are open to centron customers. Sign in to your account to ask a question about this tutorial.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren