本篇博文主要翻译这篇文章:
https://www.journaldev.com/1392/factory-design-pattern-in-java
由于翻译水平有限,自认为许多地方翻译不恰当,欢迎各位给出宝贵的建议,建议大家去阅读原文。
引言
本篇博文主要用 java 介绍 工厂模式,工厂模式是一种创建型设计模式,广泛运用在 JDK 和大量的框架中,比如 Spring 和 Struts。在什么情况下我们会用到它呢?当一个超类具有多个子类,我们需要返回其中一个子类时,就可以使用工厂模式。这个设计模式负责实例化客户端指定的类,实例化的工作由工厂类完成。
了解了一些基本概念后,接下来让我们先学一下如何利用 java 实现工厂模式,然后再去探讨工厂模式的优势。最后我们还会去看一下 JDK 中使用工厂模式的例子。这里顺便提一下,工厂模式也被称为 工厂方法设计模式。
父类
在工厂设计模式中,父类可以是一个接口、抽象类或者是一个普通的 java 类。在我们的工厂模式例子中,我们使用一个抽象类作为父类,为了测试的目的,我们还覆写了 toString 方法。
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;
}
}
这两个类都继承了 Computer 类。
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 class ComputerFactory{
public static Computer getComputer(String type,String ram,String hdd,String cpu){
if("PC".equalsIgnoreCase(type))
return new PC(ram,hdd,cpu);
else if("Server".equalsIgnoreCase))
return new Server(ram,hdd,cpu);
return null;
}
}
关于工厂模式有几个重要的点需要注意:
- 我们需要确保工厂类是单例的(Singleton),或者使用 static 修饰工厂方法。(这是一个疑惑的地方,为什么呢?)
- 根据输入参数的不同,我们返回的是不同的子类。getComputer 方法就是工厂方法。
下面是这个例子的类图:
这是对工厂方法的测试:
public class TestFactory{
public static void main(String[] args){
Computer pc = ComputerFactory.getComputer("pc","2 GB","500 GB","2.4 GHz");
Computer server = ComputerFactory.getComputer("server","16 GB","1 TB","2.9 GHz");
System.out.println("Factory PC Config::"+pc);
System.out.println("Factory Server Config::"+server);
}
}
输出的结果是
Factory PC Config::RAM= 2 GB, HDD=500 GC, CPU=2.4 GHz
Factory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
工厂模式的优点
- 工厂模式提供的是接口而不是实现
- 工厂模式将类的实例从客户端中去除,这使我们的代码更加健壮,更加易于扩展。在这个例子中,我们可以很容易的改变 PC 类的实现,因为客户端完全不知道 PC 类的实现。
- 工厂模式通过继承提供实现和客户端类之间的抽象。
JDK 中的工厂模式
-
java.util.Calendar、ResourceBundle 和 NumberFormat 的 getInstance 方法使用了工厂方法,具体的细节可以去看源码。
-
基本类型包装类的 valueOf 方法,就比如 Boolean.valueOf(boolean b )`,其实现如下,该方法会根据输入的基本类型来决定输出的实例。
public static Boolean valueOf(boolean b){ return (b ? TRUE : FALSE); }
以上就是对全文的翻译,水平有限,请见谅。