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

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

简单工厂

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

简单的示例如下:

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

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

    public abstract Product CreateProduct(string name);
}
  

Product

public abstract class Product
{

}
  

ConcreteProduct

public class ConcreteProduct : Product
{

}
  

ConcreteCreator

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;
    }
}
  

测试代码

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

抽象工厂模式

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

示例的类图如下:

使用方法示例如下:

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

示例代码

AbstractFactory

AbstractFactory.cs

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

ConcreteFactory1.cs

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

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

public interface AbstractProductA
{
}
  

ProductA1.cs

public class ProductA1: AbstractProductA
{
}
  

ProductA2.cs

public class ProductA2 : AbstractProductA
{
}
  

AbstractProductB

AbstractProductB.cs

public interface AbstractProductB
{
}
  

ProductB1.cs

public class ProductB1 : AbstractProductB
{
}
  

ProductB2.cs

public class ProductB2 : AbstractProductB
{
}
  

Client

public class Client
{
    private AbstractFactory _factory;

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

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

测试代码

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

执行结果

设计原则

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

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

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