简述
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到子类。
UML类图
Product: 产品接口,包含产品的公共属性 ConcreteProductA: 具体的产品类A,实现Product接口 ConcreteProductB: 具体的产品类B,实现Product接口 Factory: 工厂接口,定义了创建Product的接口 ConcreteFactoryA: 具体的工厂类,实现Factory接口,创建具体产品ConcreteProductA ConcreteFactoryB: 具体的工厂类,实现Factory接口,创建具体产品ConcreteProductB
案例
这里我们可以拿汽车厂商来举个例子。汽车这是一个消费产品,我们可以有具体的奔驰牌汽车,宝马牌汽车,也有对应的厂商,这就比较好理解了。
interface ICar {
//老司机开车
void drive();
}
class BMCar implements ICar {
public void drive() {
System.out.println("老司机开宝马汽车");
}
}
class BZCar implements ICar {
public void drive() {
System.out.println("老司机开奔驰汽车");
}
}
interface ICarFactory {
ICar createCar();
}
class BMFactory implements ICarFactory {
public ICar createCar() {
// 这里可以执行很多创建对象前的业务逻辑
ICar car = new BMCar();
// 这里可以添加很多初始化的事情
return car;
}
}
class BZFactory implements ICarFactory {
public ICar createCar() {
// 这里可以执行很多创建对象前的业务逻辑
ICar car = new BZCar();
// 这里可以添加很多初始化的事情
return car;
}
}
void main() {
ICarFactory bmFactory = new BMFactory();
ICar bmCar = bmFactory.createCar();
bmCar.drive();
ICarFactory bzFactory = new BZFactory();
ICar bzCar = bzFactory.createCar();
bzCar.drive();
}
最后输出为:
2020-03-14 00:44:22.718 5915-5915/com.example.javaapp I/System.out: 老司机开宝马汽车 2020-03-14 00:44:22.718 5915-5915/com.example.javaapp I/System.out: 老司机开奔驰汽车
总结
优点:
- 解决了简单工厂模式违背开闭原则的问题,同时保留了封装对象创建过程的优点,降低客户端和工厂的耦合,所以说工厂方法模式 是 简单工厂模式 的进一步抽象和推广
缺点:
- 每增加一个产品,相应的也要增加对应的产品类和对应的工厂类
适用场景
- 客户端不知道其所需要的对象的类。
- 抽象工厂接口通过其子类来指定创建哪个对象。