一、工厂方法模式的本质
工厂方法模式的本质是在简单工厂的基础上,分离简单工厂的职责,实现不同具体产品类实例创建职责分离的。(在简单工厂中,所有的产品类实例对象的创建都有同一个工厂实现,导致了工厂类的职责过多,影响了开闭原则)
工厂方法模式的核心就是为每一个具体产品类提供各自的工厂,有对应的工厂创建对应的产品类实例对象,体现了单依职责的设计理念,保证了开闭原则的遵循。
二、工厂方法模式目的
与简单工厂模式类似,工厂方法模式的核心目标也是将“类实例化的操作”与“使用对象的操作”分开,相对于简单工厂模式。
三、示例场景
同简单工厂。
某个电脑公司的在线购物网站可售卖不同型号的笔记本电脑,网站需要为客户提供电脑的配置信息查看功能,每当用户想查看某个型号的电脑配置时,需要给出该型号电脑的CPU、内存大小、硬盘类型和大小、生产日期以及价格等信息。
注意事项:该公司可能每季度都有新型号的电脑上架。
四、代码实现及对比
抽象产品类定义
public interface IThinkpad {
String getConfigInfo();
}
Thinkpad X1产品类定义
public class X1 implements IThinkpad{
String cpu;
int memory;
int hardDriveCapacity;
String hardDriveType;
/*属性的getter、setter以及toString方法省略*/
public IThinkpad createThinkPad(){
this.cpu = "英特尔 i7 10570U ";
this.memory = 32;
this.hardDriveType = "Seagate HDD";
this.hardDriveCapacity = 512;
return this;
}
public String getConfigInfo() {
return "Thinkpad X1 配置信息如下:\n--"+cpu + "\n--" + memory + "\n--" + hardDriveCapacity + "\n--" + hardDriveType;
}
}
Thinkpad X1Pro产品类定义
public class X1Pro implements IThinkpad{
String cpu;
int memory;
int hardDriveCapacity;
String hardDriveType;
/*属性的getter、setter以及toString方法省略*/
public String getConfigInfo() {
return "Thinkpad X1 Pro 配置信息如下:\n--"+cpu + "\n--" + memory + "\n--" + hardDriveCapacity + "\n--" + hardDriveType;
}
}
抽象产品工厂接口定义
public interface IThinkpadFactory {
IThinkpad createThinkpad();
}
具体产品类定义-X1具体工厂类
public class X1FactoryImpl implements IThinkpadFactory {
@Override
public IThinkpad createThinkpad() {
X1 x1 = new X1();
x1.createThinkPad();
return x1;
}
}
具体产品类定义-X1Pro具体工厂类
public class X1ProFactoryImpl implements IThinkpadFactory {
@Override
public IThinkpad createThinkpad() {
X1Pro x1Pro = new X1Pro();
x1Pro.setCpu("英特尔 i9 13770H ");
x1Pro.setMemory(64);
x1Pro.setHardDriveType("Seagate SSD");
x1Pro.setHardDriveCapacity(2048);
return x1Pro;
}
}
客户端类定义
public class com.financial.builderpattern.complex.Main {
public static void main(String[] args) {
IThinkpad x1 = new X1FactoryImpl().createThinkpad();
System.out.println(x1.getConfigInfo());
IThinkpad x1pro = new X1ProFactoryImpl().createThinkpad();
System.out.println(x1pro.getConfigInfo());
}
}
工厂方法模式中相关关系图
简单工厂模式中相关关系图
从上面两张类图可以看出,工厂方法模式就是将简单工厂模式中的工厂类进行了抽象,并针对不同的产品进行了分别实现。
现在再看看党需要增加一个产品X1ProMax类的时候,两者的不同点。
可以看出,党需要新增产品类的时候,简单工厂需要只能加一个响应的具体产品类并在工厂类中增加响应新产品类实例对象创建的逻辑。而在工厂方法模式中,仅需要增加新的具体产品类和具体产品工厂类就行。可以看出,在这样的需求场景下,简单工厂破坏了开闭原则,而工厂方法则可保证开闭原则。
五、工厂方法的UML类图
工厂方法模式中的角色:
(1)抽象产品:抽象定义产品的通用属性和方法,可以用Java中的interface或者abstract class来实现,如IThinkpad;
(2)具体产品:不同产品具有不同的属性值和方法实现,如X1、X1Pro;
(3)抽象工厂:抽象不同产品的创建方法,如IThinkpadFactory;
(4)具体工厂类:负责按照客户端的“要求”(如参数、类的类型等),提供创建具体产品类的方法,产品类的创建(即new)在此类中实现并返回抽象产品类型的具体产品实例,如X1FactoryImpl、X1ProFactoryImpl;
(5)客户端类:创建简单工厂类并向其传入相应产品的参数,接受产品工厂返回的产品类实例对象。
六、工厂方法的优缺点
(1)优点
除了具备简单工厂的优点外,相对于简单工厂,工厂方法更加符合开闭原则;
(2)缺点
增加了累的数量,相对于简单工厂,工厂方法由于针对每个产品都会有一个产品工厂类与之对应,所以其类的数量相对会增多;
与简单工厂类似,工厂方法适用于扩展多、修改少的产品类场景,如果修改原有的产品类,则相应的工厂类也可能需要修改;