设计模式之抽象工厂模式
本片博客主要翻译这篇文章:
https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java
由于翻译水平有限,自认为许多地方翻译不恰当,欢迎各位给出宝贵的建议,建议大家去阅读原文。
引言
抽象工厂模式是一种创建型模式,它和普通工厂模式很相似,一个最大的区别是其包含了工厂的工厂。如果你熟悉 工厂模式 的话,你会发现我们只有唯一一个工厂类。工厂类基于输入的参数,在内部使用 if-else 语句或者是 switch 语句的方式来输出不同的子类。
在抽象工厂设计模式中,我们放弃了 if-else 语句块,为每个子类配备一个工厂类。抽象工厂类现在依据的是输入的工厂类来输出对应的子类。刚开始我们可能会感到很困惑,但是只要我们了解了它的实现,我们就很容易发现它和工厂模式之间的区别。这里我们使用和工厂模式一样的子类和父类。
父类和子类
父类:Computer 类
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 类和 Server 类
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;
}
}
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;
}
}
工厂类和其子类
首先我们需要创建一个抽象工厂接口或者是抽象类
public interface ComputerAbstractFactory{
public Computer createComputer();
}
这里的 createComputer 方法返回父类 Computer 的一个实例,接着我们的工厂类会实现这个接口并返回各自的子类。
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 创建一个工厂类。
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);
}
}
最后,我们创建一个类,为客户端提供一个入口来创建子类。
public class ComputerFactory {
public static Computer getComputer(ComputerAbstractFactory factory){
return factory.createComputer();
}
}
我们可以看到这是一个简单的类,其只包含一个 createComputer 方法,接收 ComputerAbstractFactory 作为参数,返回 Computer 类。从这个角度来看,这个实现更加简洁。
这里写一个测试方法来看看如何使用抽象工厂类来创建 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。
- 工厂方法添加一个子类时,需要在工厂类中添加 if - else 的逻辑判断,才能输出对应的子类,抽象工厂方法很好的避免了这一点。
JDK 中的实现
- javax.xml.parsers.DocumentBuilderFactory#newInstance()
- javax.xml.transform.TransformerFactory#newInstance()
- javax.xml.xpath.XPathFactory#newInstance()
以上就是对全文的翻译,水平有限,请见谅,其中涉及的代码可以到我的 github 上下载。
本片博客主要翻译这篇文章:
https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java
由于翻译水平有限,自认为许多地方翻译不恰当,欢迎各位给出宝贵的建议,建议大家去阅读原文。
引言
抽象工厂模式是一种创建型模式,它和普通工厂模式很相似,一个最大的区别是其包含了工厂的工厂。如果你熟悉 工厂模式 的话,你会发现我们只有唯一一个工厂类。工厂类基于输入的参数,在内部使用 if-else 语句或者是 switch 语句的方式来输出不同的子类。
在抽象工厂设计模式中,我们放弃了 if-else 语句块,为每个子类配备一个工厂类。抽象工厂类现在依据的是输入的工厂类来输出对应的子类。刚开始我们可能会感到很困惑,但是只要我们了解了它的实现,我们就很容易发现它和工厂模式之间的区别。这里我们使用和工厂模式一样的子类和父类。
父类和子类
父类:Computer 类
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 类和 Server 类
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;
}
}
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;
}
}
工厂类和其子类
首先我们需要创建一个抽象工厂接口或者是抽象类
public interface ComputerAbstractFactory{
public Computer createComputer();
}
这里的 createComputer 方法返回父类 Computer 的一个实例,接着我们的工厂类会实现这个接口并返回各自的子类。
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 创建一个工厂类。
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);
}
}
最后,我们创建一个类,为客户端提供一个入口来创建子类。
public class ComputerFactory {
public static Computer getComputer(ComputerAbstractFactory factory){
return factory.createComputer();
}
}
我们可以看到这是一个简单的类,其只包含一个 createComputer 方法,接收 ComputerAbstractFactory 作为参数,返回 Computer 类。从这个角度来看,这个实现更加简洁。
这里写一个测试方法来看看如何使用抽象工厂类来创建 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。
- 工厂方法添加一个子类时,需要在工厂类中添加 if - else 的逻辑判断,才能输出对应的子类,抽象工厂方法很好的避免了这一点。
JDK 中的实现
- javax.xml.parsers.DocumentBuilderFactory#newInstance()
- javax.xml.transform.TransformerFactory#newInstance()
- javax.xml.xpath.XPathFactory#newInstance()
以上就是对全文的翻译,水平有限,请见谅,其中涉及的代码可以到我的 github 上下载。