设计模式:工厂方法模式(Factory Method)

95 阅读3分钟

一、设计模式中的工匠:工厂方法模式概述

如果说单例模式是一剑封喉的独孤剑客,那么工厂方法模式就是那位能随心所欲打造千般兵器的工匠——它的核心意图是将对象的创建推迟到子类,提供一种延迟实例化和灵活扩展的机制

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,由具体工厂 ConcreteCreatorAConcreteCreatorB 实现。它们负责创建各自的产品 ProductAProductB

二、工厂方法模式的优缺点

2.1 优点

  • 开闭原则:可以在不修改已有代码的情况下增加新产品。
  • 单一职责:将对象的创建封装在具体工厂中,减少耦合。
  • 灵活性:支持延迟实例化,按需创建。

2.2 缺点

  • 代码复杂度:增加了类的数量。
  • 额外抽象:引入了更多的抽象类和接口,可能导致理解难度上升。
  • 单一产品扩展困难:如果产品具有多个变种,可能需要更多的工厂类。

三、工厂方法模式的适用场景

适用场景:

  1. 产品类型频繁变化,且需要灵活扩展
  2. 创建的对象需要遵循某些接口规范
  3. 避免在客户端代码中显式使用具体类的构造函数

反模式警告:

  • 如果产品类型较少,且扩展需求有限,使用工厂方法可能过度设计。
  • 如果只是简单的对象创建,不需要扩展性,可以直接用简单工厂或直接实例化。

四、总结

工厂方法模式的本质在于 “推迟”——推迟具体产品的实例化,推迟复杂逻辑的暴露,推迟耦合的发生

就像一位经验丰富的工匠,不急于打造成品,而是先设计工具,再根据需求随时创造不同的产品。

这种推迟意味着:

  • 降低复杂度
  • 提高可测试性
  • 增强扩展性