当前位置:首页 > 技术知识 > 正文内容

设计模式1:简单工厂模式_工厂设计模式使用场景

maynowei9个月前 (09-29)技术知识114

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它提供了一个统一的接口来创建对象,但将具体的实例化逻辑封装在工厂类中。

模式结构

简单工厂模式包含三个主要角色:

  • 工厂类(Factory):负责创建产品对象的类
  • 抽象产品(Product):定义产品的接口
  • 具体产品(Concrete Product):实现抽象产品接口的具体类

下面是一个完整的C#简单工厂模式示例:

using System;

// 抽象产品 - 支付接口
public interface IPayment
{
    void Pay(decimal amount);
}

// 具体产品 - 支付宝支付
public class AlipayPayment : IPayment
{
    public void Pay(decimal amount)
    {
        Console.WriteLine(#34;使用支付宝支付 {amount} 元");
    }
}

// 具体产品 - 微信支付
public class WechatPayment : IPayment
{
    public void Pay(decimal amount)
    {
        Console.WriteLine(#34;使用微信支付 {amount} 元");
    }
}

// 具体产品 - 银行卡支付
public class BankCardPayment : IPayment
{
    public void Pay(decimal amount)
    {
        Console.WriteLine(#34;使用银行卡支付 {amount} 元");
    }
}

// 支付类型枚举
public enum PaymentType
{
    Alipay,
    Wechat,
    BankCard
}

// 工厂类 - 支付工厂
public class PaymentFactory
{
    public static IPayment CreatePayment(PaymentType type)
    {
        return type switch
        {
            PaymentType.Alipay => new AlipayPayment(),
            PaymentType.Wechat => new WechatPayment(),
            PaymentType.BankCard => new BankCardPayment(),
            _ => throw new ArgumentException("不支持的支付类型")
        };
    }
    
    // 另一种创建方式:通过字符串
    public static IPayment CreatePayment(string paymentType)
    {
        return paymentType.ToLower() switch
        {
            "alipay" => new AlipayPayment(),
            "wechat" => new WechatPayment(),
            "bankcard" => new BankCardPayment(),
            _ => throw new ArgumentException("不支持的支付类型")
        };
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        // 使用枚举创建支付对象
        IPayment payment1 = PaymentFactory.CreatePayment(PaymentType.Alipay);
        payment1.Pay(100.50m);
        
        IPayment payment2 = PaymentFactory.CreatePayment(PaymentType.Wechat);
        payment2.Pay(200.00m);
        
        // 使用字符串创建支付对象
        IPayment payment3 = PaymentFactory.CreatePayment("BankCard");
        payment3.Pay(150.75m);
        
        Console.ReadKey();
    }
}

可以使用反射或配置文件来使工厂更加灵活:

using System;
using System.Configuration;
using System.Reflection;

// 配置式工厂
public class ConfigurablePaymentFactory
{
    public static IPayment CreatePayment()
    {
        // 从配置文件中读取支付类型
        string paymentType = ConfigurationManager.AppSettings["PaymentType"] ?? "Alipay";
        
        // 使用反射创建实例
        string className = #34;SimpleFactoryPattern.{paymentType}Payment";
        Type type = Type.GetType(className);
        
        if (type != null && typeof(IPayment).IsAssignableFrom(type))
        {
            return (IPayment)Activator.CreateInstance(type);
        }
        
        throw new InvalidOperationException("无法创建支付实例");
    }
}

// 在App.config中添加:
// <appSettings>
//   <add key="PaymentType" value="Alipay"/>
// </appSettings>

简单工厂模式的优缺点

优点:

  1. 封装创建逻辑:将对象的创建过程封装在工厂中,客户端无需关心具体实现
  2. 解耦:客户端与具体产品类解耦,只依赖抽象接口
  3. 易于扩展:添加新产品时只需修改工厂类,符合开闭原则(对扩展开放)

缺点:

  1. 违反开闭原则(对修改关闭):添加新产品时需要修改工厂类
  2. 工厂类职责过重:所有产品创建逻辑集中在一个类中
  3. 难以扩展复杂的产品族:不适合需要创建一系列相关产品的场景

适用场景

  1. 需要创建的对象较少,不会频繁添加新产品
  2. 客户端不关心对象的创建过程,只关心使用
  3. 需要将对象的创建和使用分离
  4. 作为一个更复杂工厂模式(如工厂方法模式、抽象工厂模式)的入门

简单工厂模式是学习工厂模式的基础,虽然它不完全符合开闭原则,但在许多简单场景下仍然非常实用。

相关文章

事半功倍 轻松制作可交互移动原型

写在前面先讲个场景,看看有多少人躺枪,你在一个没有专职的交互设计师的公司做客户端的产品,基本上产品和交互的活儿你全承包了,当你准备好一切需要向领导和项目团队一起讲新版本的设计:做过WEB产品的老手,或...

iOS开发生涯的初恋:详解Objective-C多项改进

CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面。如果您想投稿、参与内容翻译工作,或寻求近匠报道,请发送...

[三菱PLC] 用&quot;C语言&quot;玩转PLC,三菱PLC使用ST语言超详细教程

ST语言,全称为结构化文本(Structured Text),是一种高级编程语言,专为工业自动化和控制系统设计。我们学习PLC一般是用梯形图,梯形图学会后,学习SFC,但是我发现梯形图和SFC虽然简单...

如何优雅地使用嵌入式事件标志组?

事件标志组嵌入式事件标志组是一种在嵌入式系统中广泛使用的同步机制,主要用于实现多任务间的同步与通信。事件标志组是一组事件标志位的集合,每个位代表一个事件是否发生。它允许任务等待特定的事件发生,当事件发...

C++11 同步机制:互斥锁和条件变量

前段时间,我研究了 ROS2(Jazzy)机器人开发系统,并将官网中比较重要的教程和概念,按照自己的学习顺序翻译成了中文,进行了整理和记录。到目前为止,已经整理了20多篇文章。如果你想回顾之前的内容,...

Linux系统编程:条件变量为什么要用锁

条件变量可以解决线程同步和共享资源访问的问题,条件变量是对互斥锁的补充,它允许一个线程阻塞并等待另一个线程发送的信号,当收到信号时,阻塞的线程被唤醒并试图锁定与之相关的互斥锁。具体定义如下:等待:in...