Khóa học java

Abstract Factory Pattern trong Java

0 phút đọc

Abstract Factory Pattern, còn gọi là Factory of Factories, là một mẫu thiết kế tạo dựng (Creation Pattern). Nó tương tự như Factory Pattern, nhưng cung cấp một mức trừu tượng hơn để tạo ra các đối tượng liên quan đến nhau.

Abstract Factory Pattern là gì?

Nếu bạn đã quen thuộc với Factory Pattern, bạn biết rằng nó chỉ sử dụng một lớp Factory duy nhất để tạo ra các đối tượng con (sub-class) dựa trên đầu vào (thường sử dụng if-else hoặc switch để xác định lớp con nào sẽ được trả về).

Abstract Factory Pattern cũng liên quan đến việc tạo đối tượng, nhưng nó nâng cấp điểm yếu của Factory Pattern. Thay vì sử dụng if-else hoặc switch để xác định đối tượng con cụ thể, Abstract Factory Pattern sử dụng một cấu trúc dạng hình thức để quyết định đối tượng nào sẽ được tạo ra.

Một số ví dụ về Abstract Factory Pattern trong JDK (Java Development Kit) bao gồm:

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

Lợi ích của Abstract Factory Pattern:

  • Cung cấp hướng tiếp cận code thông qua giao diện (interface) thay vì sử dụng cài đặt cụ thể, giống với Factory Pattern.
  • Có thể mở rộng dễ dàng bằng cách thêm các Factory và các đối tượng con mới mà không làm thay đổi code hiện tại.
  • Giúp tránh việc sử dụng các điều kiện logic như if-else bên trong Factory Pattern.

Abstract Factory Pattern UML Diagram

Cũng giống như Factory Pattern, chúng ta sẽ sử dụng các super class, sub-class

Abstract Factory Pattern UML Diagram

Abstract Factory Pattern sử dụng các lớp cha và lớp con, tương tự như Factory Pattern. Tuy nhiên, khác biệt quan trọng nằm ở việc có nhiều lớp Factory (ConcreteFactory_1, ConcreteFactory_2) cùng triển khai một Interface trừu tượng (AbstractFactory). Mỗi lớp Factory này sẽ trả về các đối tượng khác nhau.

Ví dụ về Abstract Factory

Giả sử chúng ta có một class cha là Computer và hai class con là ServerPC. Chúng ta muốn tạo các đối tượng Server hoặc PC dựa trên dữ liệu đầu vào.

ComputerAbstractFactory là một interface cung cấp phương thức trả về đối tượng Computer.

ServerFactoryPCFactory sẽ cài đặt các phương thức của ComputerAbstractFactory.

ComputerFactory sẽ sử dụng ComputerAbstractFactory để tạo đối tượng Computer. (Trường hợp ComputerAbstractFactoryServerFactory thì sẽ trả về đối tượng Server, trường hợp ComputerAbstractFactoryPCFactory thì sẽ trả về đối tượng PC)

image

Các Lớp

// Lớp cha
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();
    }
}

// Lớp con 1
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;
    }
}

// Lớp con 2
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;
    }
}

Các Interface và Lớp Factory

// Interface trừu tượng
public interface ComputerAbstractFactory {
    public Computer createComputer();
}

// Lớp Factory cho 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);
    }
}

// Lớp Factory cho 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);
    }
}

Lớp Factory chính

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

Demo

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

    private static void testAbstractFactory() {
        Computer pc = ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));
        Computer server = 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);
    }
}

Kết quả

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

Bây giờ, nếu chúng ta muốn thêm một lớp con khác, ví dụ như Laptop, chúng ta chỉ cần tạo lớp LaptopLaptopFactory tương ứng mà không cần sửa đổi code hiện tại.

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào

Avatar
Được viết bởi

TechMely Team