Skip to content

Head First 设计模式 04-工厂模式

🏷️ 《Head First 设计模式》

工厂模式可能是项目中最常见的模式了,不过大部分使用的都是 简单工厂

简单工厂

简单工厂其实不是一种设计模式,反而比较像是一种编程习惯。

简单的示例如下:

csharp
class ProductFactory
{
    public Product CreateProduct(string type)
    {
        Product product = null;

        switch (type)
        {
            case "A":
                product = new ProductA();
                break;
            case "B":
                product = new ProductB();
                break;
            default:
                break;
        }

        return product;
    }
}

工厂方法模式

工厂方法模式 定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

下面类图中的 CreateProduct 方法即是工厂方法,其具体实现在 ConcreteCrreator 类中。

示例代码

Creator

csharp
public abstract class Creator
{
    public void Operation()
    {
        Console.WriteLine("Do some operation.");
    }

    public abstract Product CreateProduct(string name);
}

Product

csharp
public abstract class Product
{

}

ConcreteProduct

csharp
public class ConcreteProduct : Product
{

}

ConcreteCreator

csharp
public class ConcreteCreator : Creator
{
    public override Product CreateProduct(string name)
    {
        Product product = null;

        switch (name)
        {
            case "Concrete":
                product = new ConcreteProduct();
                Console.WriteLine("You create a concrete product.");
                break;
            default:
                break;
        }

        return product;
    }
}

测试代码

csharp
Creator creator = new ConcreteCreator();
creator.Operation();
Product product = creator.CreateProduct("Concrete");

抽象工厂模式

抽象工厂模式 提供一个接口,用于创建相关或依赖对象的 家族 ,而不需要明确指定具体类。

示例的类图如下:

使用方法示例如下:

csharp
Client client1 = new Client(new ConcreteFactory1());
client1.DoSomeOperation();
Client client2 = new Client(new ConcreteFactory2());
client2.DoSomeOperation();

示例代码

AbstractFactory

AbstractFactory.cs

csharp
public interface AbstractFactory
{
    AbstractProductA CreateProductA();
    AbstractProductB CreateProductB();
}

ConcreteFactory1.cs

csharp
public class ConcreteFactory1 : AbstractFactory
{
    public AbstractProductA CreateProductA()
    {
        Console.WriteLine("Create a ProductA1.");
        return new ProductA1();
    }

    public AbstractProductB CreateProductB()
    {
        Console.WriteLine("Create a ProductB1.");
        return new ProductB1();
    }
}

ConcreteFactory2.cs

csharp
public class ConcreteFactory2 : AbstractFactory
{
    public AbstractProductA CreateProductA()
    {
        Console.WriteLine("Create a ProductA2.");
        return new ProductA2();
    }

    public AbstractProductB CreateProductB()
    {
        Console.WriteLine("Create a ProductB2.");
        return new ProductB2();
    }
}

AbstractProductA

AbstractProductA.cs

csharp
public interface AbstractProductA
{
}

ProductA1.cs

csharp
public class ProductA1: AbstractProductA
{
}

ProductA2.cs

csharp
public class ProductA2 : AbstractProductA
{
}

AbstractProductB

AbstractProductB.cs

csharp
public interface AbstractProductB
{
}

ProductB1.cs

csharp
public class ProductB1 : AbstractProductB
{
}

ProductB2.cs

csharp
public class ProductB2 : AbstractProductB
{
}

Client

csharp
public class Client
{
    private AbstractFactory _factory;

    public Client(AbstractFactory factory)
    {
        _factory = factory;
    }

    public void DoSomeOperation()
    {
        var productA = _factory.CreateProductA();
        var productB = _factory.CreateProductB();
    }
}

测试代码

csharp
Client client1 = new Client(new ConcreteFactory1());
client1.DoSomeOperation();
Client client2 = new Client(new ConcreteFactory2());
client2.DoSomeOperation();

执行结果

设计原则

No.6 依赖倒置原则(Dependency Inversion Principle

要依赖抽象,不要依赖具体类。

  • 变量不可以持有具体类的引用。
  • 不要让类派生自具体类。
  • 不要覆盖基类中已实现的方法。