一、设计模式中的工匠:工厂方法模式概述
如果说单例模式是一剑封喉的独孤剑客,那么工厂方法模式就是那位能随心所欲打造千般兵器的工匠——它的核心意图是将对象的创建推迟到子类,提供一种延迟实例化和灵活扩展的机制。
1.1 设计意图
工厂方法模式主要解决两个问题:
- 对象创建的复杂性:避免直接依赖具体类的构造函数,减少耦合。
- 扩展灵活性:在不修改已有代码的情况下增加新产品类型。
1.2 基本结构
经典的工厂方法模式包含以下几个核心角色:
- 抽象工厂(Creator):定义工厂方法,返回一个产品对象。
- 具体工厂(ConcreteCreator):实现工厂方法,生产具体产品。
- 抽象产品(Product):定义产品的公共接口。
- 具体产品(ConcreteProduct):实现具体的产品逻辑。
// 抽象产品
public interface IProduct
{
void Operation();
}
// 具体产品A
public class ProductA : IProduct
{
public void Operation() => Console.WriteLine("ProductA is operating.");
}
// 具体产品B
public class ProductB : IProduct
{
public void Operation() => Console.WriteLine("ProductB is operating.");
}
// 抽象工厂
public abstract class Creator
{
public abstract IProduct CreateProduct();
public void SomeOperation()
{
var product = CreateProduct();
product.Operation();
}
}
// 具体工厂A
public class ConcreteCreatorA : Creator
{
public override IProduct CreateProduct() => new ProductA();
}
// 具体工厂B
public class ConcreteCreatorB : Creator
{
public override IProduct CreateProduct() => new ProductB();
}
// 测试
class Program
{
static void Main(string[] args)
{
Creator factoryA = new ConcreteCreatorA();
factoryA.SomeOperation();
Creator factoryB = new ConcreteCreatorB();
factoryB.SomeOperation();
}
}
1.3 运行结果
ProductA is operating.
ProductB is operating.
在这个结构中,Creator 定义了工厂方法 CreateProduct,由具体工厂 ConcreteCreatorA 和 ConcreteCreatorB 实现。它们负责创建各自的产品 ProductA 和 ProductB。
二、工厂方法模式的优缺点
2.1 优点
- 开闭原则:可以在不修改已有代码的情况下增加新产品。
- 单一职责:将对象的创建封装在具体工厂中,减少耦合。
- 灵活性:支持延迟实例化,按需创建。
2.2 缺点
- 代码复杂度:增加了类的数量。
- 额外抽象:引入了更多的抽象类和接口,可能导致理解难度上升。
- 单一产品扩展困难:如果产品具有多个变种,可能需要更多的工厂类。
三、工厂方法模式的适用场景
✅ 适用场景:
- 产品类型频繁变化,且需要灵活扩展。
- 创建的对象需要遵循某些接口规范。
- 避免在客户端代码中显式使用具体类的构造函数。
❌ 反模式警告:
- 如果产品类型较少,且扩展需求有限,使用工厂方法可能过度设计。
- 如果只是简单的对象创建,不需要扩展性,可以直接用简单工厂或直接实例化。
四、总结
工厂方法模式的本质在于 “推迟”——推迟具体产品的实例化,推迟复杂逻辑的暴露,推迟耦合的发生。
就像一位经验丰富的工匠,不急于打造成品,而是先设计工具,再根据需求随时创造不同的产品。
这种推迟意味着:
- 降低复杂度
- 提高可测试性
- 增强扩展性