Trang chủHướng dẫnMẫu thiết kế Abstract Factory trong Java
Java

Mẫu thiết kế Abstract Factory trong Java

CyStack blog 4 phút để đọc
CyStack blog11/07/2025
Locker Avatar

Bao Tran

Web Developer

Locker logo social
Reading Time: 4 minutes

Chào mừng bạn đến với ví dụ về mẫu thiết kế Abstract Factory trong Java ( Abstract Factory Design Pattern in Java). Abstract Factory là một trong những mẫu thiết kế thuộc nhóm Creational patterns. Abstract Factory pattern gần giống với Factory Pattern, điểm khác biệt là nó giống như một “nhà máy của các nhà máy” – tức là nó tạo ra các Factory khác nhau.

Abstract Factory Pattern trong Java

Abstract Factory

Nếu bạn đã quen với factory design pattern trong Java, bạn sẽ nhận thấy rằng chúng ta chỉ có một lớp Factory duy nhất. Lớp factory này sẽ trả về các lớp con (sub-class) khác nhau dựa vào đầu vào, thường sử dụng cấu trúc if-else hoặc switch để thực hiện điều này.

Trong Abstract Factory pattern, chúng ta loại bỏ khối if-else đó và tạo một lớp factory riêng cho mỗi lớp con. Sau đó sẽ có một lớp Abstract Factory dùng để trả về lớp con tương ứng thông qua lớp factory cụ thể.

Thoạt đầu có vẻ khó hiểu, nhưng khi bạn nhìn vào phần cài đặt, sẽ thấy khá dễ hiểu và dễ phân biệt sự khác nhau giữa Factory và Abstract Factory pattern. Giống như bài viết về factory pattern trước đây, chúng ta sẽ sử dụng cùng một lớp cha (superclass) và các lớp con.

Abstract Factory Design Pattern – Lớp cha và các lớp con

Computer.java

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

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

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;
    }
 
}

Lớp Factory cho mỗi lớp con

Trước tiên, chúng ta cần tạo một interface hoặc lớp abstract ****cho Abstract Factory.

ComputerAbstractFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public interface ComputerAbstractFactory {

	public Computer createComputer();

}

Chú ý rằng phương thức createComputer() sẽ trả về một instance của lớp cha Computer. Bây giờ các lớp factory của chúng ta sẽ triển khai interface này và trả về lớp con tương ứng.PCFactory.java

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);
	}

}

Tương tự, chúng ta sẽ có một lớp factory cho lớp con Server. ServerFactory.java

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);
	}

}

Bây giờ, chúng ta sẽ tạo một lớp consumer để cung cấp điểm khởi đầu cho các lớp client khi muốn tạo ra các lớp con. ComputerFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public class ComputerFactory {

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

Lưu ý rằng đây là một lớp đơn giản và phương thức getComputer nhận một đối tượng ComputerAbstractFactory làm tham số và trả về một đối tượng Computer. Ở thời điểm này, phần cài đặt chắc chắn đã trở nên rõ ràng hơn. Hãy viết một phương thức kiểm thử đơn giản để xem cách sử dụng abstract factory để lấy instance của các lớp con. TestDesignPatterns.java

package com.journaldev.design.test;

import com.journaldev.design.abstractfactory.PCFactory;
import com.journaldev.design.abstractfactory.ServerFactory;
import com.journaldev.design.factory.ComputerFactory;
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);
	}
}

Output của chương trình trên sẽ là:

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

Đây là sơ đồ lớp (class diagram) của phần cài đặt abstract factory design pattern.

Abstract Factory Pattern

 

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

  • Abstract Factory cung cấp cách tiếp cận lập trình hướng interface thay vì cụ thể vào implementation.
  • Abstract Factory là một “nhà máy của các nhà máy” và có thể dễ dàng mở rộng để hỗ trợ thêm sản phẩm mới, ví dụ như thêm lớp con Laptop và một lớp factory LaptopFactory.
  • Abstract Factory mang tính mở rộng cao và tránh được logic điều kiện (if-else) như trong Factory pattern.

Ví dụ sử dụng Abstract Factory Design Pattern trong JDK

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

Video hướng dẫn về Abstract Factory Design Pattern

Gần đây tôi có đăng một video trên YouTube về abstract factory design pattern. Trong video đó, tôi chia sẻ khi nào và làm sao để triển khai mẫu thiết kế này. Tôi cũng đã giải thích sự khác nhau giữa factory patternabstract factory design pattern.

https://youtu.be/BPkYkyVWOaw

Bạn có thể tải mã ví dụ từ dự án GitHub của tôi.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất