1. 基本概念
1.1 什么是抽象工厂模式?
抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
看起来是多个 工厂方法模式 的堆叠
抽象工厂模式依赖于多态,工厂方法模式依赖于继承
1.2 基本解决方法
1.3 应用场景
-
如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
抽象工厂为你提供了接口(看起来就是多个工厂方法), 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象, 那么你就不会生成与应用程序已生成的产品类型不一致的产品。 -
如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。
在设计良好的程序中, 每个类仅负责一件事。 如果一个类与多种类型产品交互, 就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。
1.4 优缺点
优点
- 你可以确保同一工厂生成的产品相互匹配。
- 你可以避免客户端和具体产品代码的耦合。
- 单一职责原则。 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。
- 开闭原则。 向应用程序中引入新产品变体时, 你无需修改客户端代码。
缺点
- 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。
2. 实现方式
- 以不同的产品类型与产品变体为维度绘制矩阵。
- 为所有产品声明抽象产品接口。 然后让所有具体产品类实现这些接口。
- 声明抽象工厂接口, 并且在接口中为所有抽象产品提供一组构建方法。(一组工厂方法)
- 为每种产品变体实现一个具体工厂类。
- 在应用程序中开发初始化代码。 该代码根据应用程序配置或当前环境,对特定具体工厂类进行初始化。 然后将该工厂对象传递给所有需要创建产品的类。
- 找出代码中所有对产品构造函数的直接调用, 将其替换为对工厂对象中相应构建方法的调用。
3. 实现示例
通用产品接口
// A 类产品
public interface Transport {
void diliver();
}
// B 类产品
public interface Driver {
void drive();
}
具体产品
// A 类产品具体实现
public class Car implements Transport {
public void diliver() {
System.out.println("car diliver");
}
}
public class Boat implements Transport {
public void diliver() {
System.out.println("boat diliver");
}
}
// B类产品具体实现
public class CarDriver implements Driver {
public void drive() {
System.out.println("carDriver drive");
}
}
public class BoatDriver implements Driver {
public void drive() {
System.out.println("boatDriver drive");
}
}
factory
抽象工厂
public interface CreatorFactory {
// 工厂方法
Transport createTransport();
Driver createDriver();
}
具体工厂
public class PostOffice implements CreatorFactory {
@Override
public Transport createTransport() {
return new Car();
}
@Override
public Driver createDriver() {
return new CarDriver();
}
}
public class SeaPostOffice implements CreatorFactory {
@Override
public Transport createTransport() {
return new Boat();
}
@Override
public Driver createDriver() {
return new BoatDriver();
}
}
客户端:
public class Application {
private Transport transport;
private Driver driver;
public Application(CreatorFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void runBusinessLogic() {
transport.deliver();
driver.drive();
}
}