创建型模式
- 工厂方法模式(Factory Method Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
- 单例模式(Singleton Pattern)
抽象工厂模式(Abstract Factory Pattern) 是一种创建型设计模式,它提供了一种接口,用于创建一系列相关或相互依赖的对象,而不需要指定具体类。该模式的关键在于通过抽象化的工厂方法来生成具体的对象集合,确保这些对象在某一产品族内是兼容的。抽象工厂模式通常被用来处理一系列产品的创建,并且在这些产品之间需要保持一致性。
关键概念
- AbstractFactory(抽象工厂):定义创建一组相关对象的接口。
- ConcreteFactory(具体工厂):实现
AbstractFactory
接口,负责创建具体的产品对象。 - AbstractProduct(抽象产品):定义一类产品的接口。
- ConcreteProduct(具体产品):实现
AbstractProduct
接口,提供具体的产品实现。 - Client(客户端):通过使用
AbstractFactory
来创建产品对象,但无需关心具体工厂或产品的实现。
适用场景
- 产品族的需求:当系统需要从多个产品系列中选择时(比如不同操作系统的UI组件),可以使用抽象工厂模式。
- 产品之间存在依赖关系:当某些产品之间需要高度的协作,抽象工厂可以确保所有产品在同一产品族中兼容。
- 客户端需要独立于具体产品:客户端仅通过抽象工厂接口与产品交互,不关心具体产品的实现类。
优缺点分析
优点:
- 符合开闭原则:客户端不需要修改代码,只需要新增一个工厂类即可扩展功能。
- 产品族的统一性:所有产品都来自同一个工厂,因此确保它们在同一产品族中是兼容的。
- 提高系统的可扩展性:可以方便地增加新的产品族(即新类型的产品),只需要添加新的具体工厂和具体产品类。
缺点:
- 增加系统的复杂度:需要创建多个工厂类和产品类,导致系统的复杂性增加。
- 扩展困难:如果需要增加一个新产品类型,可能需要修改所有的工厂类和相关代码。
假设你经营一家家具公司,你的公司生产不同风格的家具:现代风格和传统风格。每种风格的家具包含不同的类型,比如桌子、椅子等。抽象工厂模式能够帮助我们在不修改客户端代码的情况下,灵活地生产各种风格的家具。
例子:家具工厂
1. 定义抽象产品接口
我们定义两类产品:桌子(Table
)和椅子(Chair
)。
// 抽象产品A(桌子)
public interface Table {
void create();
}
// 抽象产品B(椅子)
public interface Chair {
void create();
}
2. 定义具体产品类
每种风格的家具都有不同的实现类。例如,现代风格和传统风格的桌子和椅子会有所不同。
// 现代风格的桌子
public class ModernTable implements Table {
@Override
public void create() {
System.out.println("Creating a modern table.");
}
}
// 现代风格的椅子
public class ModernChair implements Chair {
@Override
public void create() {
System.out.println("Creating a modern chair.");
}
}
// 传统风格的桌子
public class TraditionalTable implements Table {
@Override
public void create() {
System.out.println("Creating a traditional table.");
}
}
// 传统风格的椅子
public class TraditionalChair implements Chair {
@Override
public void create() {
System.out.println("Creating a traditional chair.");
}
}
3. 定义抽象工厂接口
抽象工厂接口提供了创建家具的方法(创建桌子和椅子)。
// 抽象工厂接口
public interface FurnitureFactory {
Table createTable();
Chair createChair();
}
4. 定义具体工厂类
每个具体工厂类负责生产特定风格的家具。
// 现代风格的家具工厂
public class ModernFurnitureFactory implements FurnitureFactory {
@Override
public Table createTable() {
return new ModernTable();
}
@Override
public Chair createChair() {
return new ModernChair();
}
}
// 传统风格的家具工厂
public class TraditionalFurnitureFactory implements FurnitureFactory {
@Override
public Table createTable() {
return new TraditionalTable();
}
@Override
public Chair createChair() {
return new TraditionalChair();
}
}
5. 客户端代码
客户端通过抽象工厂来创建产品,而不需要关注具体产品的实现。
// 客户端代码
public class FurnitureShop {
private Table table;
private Chair chair;
public FurnitureShop(FurnitureFactory factory) {
// 使用工厂创建产品
table = factory.createTable();
chair = factory.createChair();
}
public void displayFurniture() {
table.create();
chair.create();
}
public static void main(String[] args) {
// 假设从外部配置获取客户需求
String style = "Modern"; // 可以是 "Modern" 或 "Traditional"
FurnitureFactory factory;
if (style.equals("Modern")) {
factory = new ModernFurnitureFactory();
} else {
factory = new TraditionalFurnitureFactory();
}
FurnitureShop shop = new FurnitureShop(factory);
shop.displayFurniture();
}
}
总结
这个例子展示了如何通过抽象工厂模式来创建一系列相关的家具产品(桌子和椅子)。不同风格的家具由不同的工厂生产,客户端只需要依赖于抽象工厂接口来创建和使用家具,而无需关心具体的实现。这种方式提高了系统的灵活性,方便扩展新的家具风格,也避免了客户端和具体产品之间的紧耦合。