使用工厂模式创建对象时,我们不需要对客户端暴露创建逻辑,只需要通过一个共同的接口(工厂)来创建即可,从而使得代码简洁易懂。
工厂方法模式中有以下几个元素:
- 产品:要创建的对象
- 工厂:用于创建产品的媒介
在介绍工厂方法模式之前,先介绍一下简单工厂
简单工厂的实现十分简单:
- 共同的产品接口
- 产品类实现产品接口
- 提供工厂类,用于创建不同的产品
以生产汽车为例
1.共同的产品接口
public interface Car {
void run();
}
2.具体的产品
public class Audi implements Car{
@Override
public void run() {
System.out.println("Audi run");
}
}
public class Byd implements Car {
@Override
public void run() {
System.out.println("Byd run");
}
}
3.创建工厂类,用于获取某一个具体的工厂
以下两种方式获取创建工厂类
方式一:通过传入字符串确定创建的产品
public class CarFactory {
public static Car createCar(String type) {
Car c = null;
if ("Audi".equals(type)) {
c = new Audi();
} else if ("Byd".equals(type)) {
c = new Byd();
}
return c;
}
}
方式二:对每一种产品提供一个创建类
public class CarFactory {
public static Car createByd() {
return new Byd();
}
public static Car createAudi() {
return new Audi();
}
}
使用时,直接调用工厂类获取某个具体的产品
public static void main(String[] args) {
Car car1 = CarFactory.createAudi();
car1.run();
Car car2 = CarFactory.createByd();
car2.run();
}
简单工厂的结构十分简单易懂,但是从上例可以看出,简单工厂的扩展性很差。
如果我们要增加一个产品,则必须
1. 添加一个产品类
2. 添加相应的工厂方法
针对这个缺点,工厂方法模式进行了改进,准确来说,是针对第2点进行了改进。
上例中的产品接口和产品类我们暂时不修改,我们丢掉原来的工厂类,修改如下:
- 将工厂类接口化
- 具体的工厂生产具体的产品
1.工厂类接口化
public interface CarFactory {
Car createCar();
}
2.具体的工厂生产具体的产品
public class AudiFactory implements CarFactory{
@Override
public Car createCar() {
return new Audi();
}
}
public class BydFactory implements CarFactory{
@Override
public Car createCar() {
return new Byd();
}
}
这样我们在调用的时候,只需要指定特定的工厂,就能产生相应的产品了
public static void main(String[] args) {
Car car1 = new BydFactory().createCar();
car1.run();
Car car2 = new AudiFactory().createCar();
car2.run();
}
如果要增加一件产品,在工厂方法模式中,只需要添加相应的实现类和实现工厂即可,不需要进入工厂类之中修改代码了。
但是比较简单工厂可以看出,工厂方法模式的缺点在于扩展的时候需要改动的内容变多了,不够简洁
这里简单总结一下简单工厂和工厂方法模式
简单工厂模式:
- 工厂类一般使用静态方法,通过接收的参数的不同来返回不同的对象
- 对于增加新产品无能为力,不修改代码的话,是无法扩展的。
工厂方法模式:
- 避免了简单工厂模式的缺点,扩展性好,但较繁琐
- 工厂方法模式和简单工厂模式的最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类