Java 中的抽象工廠設計模式

歡迎來到Java中的抽象工廠設計模式示例。抽象工廠設計模式是創建型模式之一。抽象工廠模式與工廠模式幾乎相同,唯一的區別在於它更像是工廠的集合。

抽象工廠

如果您熟悉Java中的工廠設計模式,您會注意到我們只有一個工廠類。這個工廠類根據提供的輸入返回不同的子類,並使用if-else或switch語句來實現這一點。在抽象工廠模式中,我們消除了if-else塊,為每個子類都有一個工廠類。然後,有一個抽象工廠類,根據輸入的工廠類返回相應的子類。一開始可能會感到困惑,但一旦看到實現,就會發現工廠模式和抽象工廠模式之間的細微差異非常容易理解。就像我們的工廠模式文章一樣,我們將使用相同的超類和子類。

抽象工廠設計模式超類和子類

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

每個子類的工廠類

首先,我們需要創建一個抽象工廠接口或抽象類ComputerAbstractFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public interface ComputerAbstractFactory {

	public Computer createComputer();

}

注意,createComputer() 方法返回超類 Computer 的實例。現在,我們的工廠類將實現此接口並返回其相應的子類。 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);
	}

}

同樣,我們將為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);
	}

}

現在,我們將創建一個消費者類,該類將為客戶端類創建子類提供入口。 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();
	}
}

請注意,這是一個簡單的類別,getComputer方法接受ComputerAbstractFactory參數並返回Computer對象。在這一點上,實現應該已經變得清晰。讓我們編寫一個簡單的測試方法,並看看如何使用抽象工廠來獲取子類的實例。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);
	}
}

上述程序的輸出將是:

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

這是抽象工廠設計模式實現的類圖。

抽象工廠設計模式的好處

  • 抽象工廠設計模式提供了為接口編碼而不是實現的方法。
  • 抽象工廠模式是“工廠的工廠”,可以很容易地擴展以容納更多的產品,例如,我們可以添加另一個子類Laptop和一個工廠LaptopFactory。
  • 抽象工廠模式是健壯的,並避免了工廠模式的條件邏輯。

JDK 中的抽象工厂设计模式示例

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

抽象工厂设计模式视频教程

I recently uploaded a video on YouTube for abstract factory design pattern. In the video, I discuss when and how to implement an abstract factory pattern. I have also discussed what is the difference between the factory pattern and abstract factory design pattern. https://youtu.be/BPkYkyVWOaw

你可以从我的GitHub 项目下载示例代码。

Source:
https://www.digitalocean.com/community/tutorials/abstract-factory-design-pattern-in-java