C# 23种设计模式(2)简单工厂(SimpleFactory)模式

发布于:2024-12-18 ⋅ 阅读:(47) ⋅ 点赞:(0)

一、简单工厂模式介绍

  1. 定义:简单工厂模式(Simple Factory Pattern),又称为静态工厂模式(Static Factory Pattern),是一种创建型设计模式。它专门定义一个类来负责创建其他类的实例,这些被创建的实例通常具有共同的父类,并且可以根据参数的不同返回不同类的实例。

  2. 结构:简单工厂模式包含三个角色:

    • 工厂角色:负责实现创建所有实例的内部逻辑。
    • 抽象产品角色:是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。
    • 具体产品角色:是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
  3. 用途

  • 封装对象的创建:将对象的创建过程封装在工厂类中,客户端不需要知道对象是如何被创建的。
  • 解耦:降低了客户端与具体产品类之间的耦合度,使得系统更加灵活和可扩展。
  • 便于维护:当需要修改对象的创建过程时,只需修改工厂类,而不需要修改客户端代码。

二、简单工厂模式代码实现

  假设我们有一个接口Product,以及两个实现了该接口的具体产品类ConcreteProductAConcreteProductB

// 产品接口
public interface Product
{
    string Barcode { get; } // 假设条码是只读的
    void Use();
}

// 具体产品A
public class ConcreteProductA : Product
{
    public string Barcode { get; private set; } = "A12345"; // 为产品A分配一个条码

    public void Use()
    {
        Console.WriteLine("Using ConcreteProductA with Barcode: " + Barcode);
    }
}

// 具体产品B
public class ConcreteProductB : Product
{
    public string Barcode { get; private set; } = "B67890"; // 为产品B分配一个条码

    public void Use()
    {
        Console.WriteLine("Using ConcreteProductB with Barcode: " + Barcode);
    }
}

// 工厂类(无需修改,因为接口的变化没有影响到工厂类的创建逻辑)
public class SimpleFactory
{
    public static Product CreateProduct(string type)
    {
        Product product = null;
        switch (type)
        {
            case "A":
                product = new ConcreteProductA();
                break;
            case "B":
                product = new ConcreteProductB();
                break;
            default:
                throw new ArgumentException("Unknown product type");
        }
        return product;
    }
}

// 客户端代码(无需修改,因为接口的变化没有影响到客户端的使用方式)
public class Client
{
    public static void Main()
    {
        Product productA = SimpleFactory.CreateProduct("A");
        productA.Use(); // 输出: Using ConcreteProductA with Barcode: A12345

        Product productB = SimpleFactory.CreateProduct("B");
        productB.Use(); // 输出: Using ConcreteProductB with Barcode: B67890
    }
}

SimpleFactory类根据传入的字符串参数type来创建并返回相应的Product对象。客户端代码通过调用SimpleFactory.CreateProduct方法来获取所需的产品对象,而无需知道具体的产品实现类。这样就实现了对象的创建与使用之间的解耦。

三、简单工厂代码在C#中的升级

SimpleFactory类的枚举在每次增加新的产品类时,都要需要修改一下枚举,非常的麻烦。但是C#本身提供了泛型<T>,完全可以将产品类作为泛型对象传入,然后直接创建这个产品类对象,再以父类形式返回。

代码实现如下(在原来SimpleFactory类代码上增加了一个重载函数,和调用代码):

// 产品接口
public interface Product
{
    string Barcode { get; } // 假设条码是只读的
    void Use();
}

// 具体产品A
public class ConcreteProductA : Product
{
    public string Barcode { get; private set; } = "A12345"; // 为产品A分配一个条码

    public void Use()
    {
        Console.WriteLine("Using ConcreteProductA with Barcode: " + Barcode);
    }
}

// 具体产品B
public class ConcreteProductB : Product
{
    public string Barcode { get; private set; } = "B67890"; // 为产品B分配一个条码

    public void Use()
    {
        Console.WriteLine("Using ConcreteProductB with Barcode: " + Barcode);
    }
}

// 工厂类(无需修改,因为接口的变化没有影响到工厂类的创建逻辑)
public class SimpleFactory
{
    public static Product CreateProduct(string type)
    {
        Product product = null;
        switch (type)
        {
            case "A":
                product = new ConcreteProductA();
                break;
            case "B":
                product = new ConcreteProductB();
                break;
            default:
                throw new ArgumentException("Unknown product type");
        }
        return product;
    }
    public static Product CreateProduct<T>()
    {
        return (Product)Activator.CreateInstance(typeof(T));
    }
}


// 客户端代码(无需修改,因为接口的变化没有影响到客户端的使用方式)
public class Client1
{
    public static void Main1()
    {
        var product_a=SimpleFactory.CreateProduct<ConcreteProductA>();
        var product_b=SimpleFactory.CreateProduct<ConcreteProductB>();
        product_a.Use();// 输出: Using ConcreteProductA with Barcode: A12345
        product_b.Use();// 输出: Using ConcreteProductB with Barcode: B67890

        Product productA = SimpleFactory.CreateProduct("A");
        productA.Use(); // 输出: Using ConcreteProductA with Barcode: A12345

        Product productB = SimpleFactory.CreateProduct("B");
        productB.Use(); // 输出: Using ConcreteProductB with Barcode: B67890
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到