C#面向对象的23种设计模式介绍

C#面向对象的23种设计模式介绍》是一篇系统性的介绍C#中常见23种设计模式的文章。下面我将为大家详细讲解这篇文章的完整攻略:

一、前言

文章先介绍了设计模式的概念和作用,以及在软件开发中为什么需要设计模式。同时也会提醒读者,设计模式仅仅是一种思想上的借鉴,不能盲目使用。

二、设计模式的分类

文章接着介绍了设计模式的分类方式,分为三类:创建型模式、结构型模式和行为型模式。分别列举了各类设计模式的特点和使用场景。

三、设计模式的具体介绍

在这一部分,会详细介绍每一种设计模式的定义、实现、优缺点以及代码示例等内容。

1. 创建型模式

工厂方法模式

工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。

在此模式下,具体的工厂由抽象工厂类的派生类实现,在工厂类中调用抽象产品类中定义的方法,返回抽象产品类的实例。

例如,我们需要创建一个接口为IFruit的对象,并且具体实现类为Apple,则可以使用如下代码:

public class Program
{
    static void Main(string[] args)
    {
        // 创建手机工厂对象
        IFruitFactory fruitFactory = new AppleFactory();
        // 生产手机
        IFruit fruit = fruitFactory.Create();
        // 显示手机信息
        fruit.Show();
    }
}

public interface IFruit
{
    void Show();
}

public class Apple : IFruit
{
    public void Show()
    {
        Console.WriteLine("This is an apple.");
    }
}

public interface IFruitFactory
{
    IFruit Create();
}

public class AppleFactory : IFruitFactory
{
    public IFruit Create()
    {
        return new Apple();
    }
}

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。

在此模式下,抽象工厂类定义了一系列方法,具体工厂类实现这些方法,并返回一系列相关对象。

例如,我们需要创建一个手机产品,在此基础上又要有不同的版本(例如屏幕大小、像素等参数)。则可以使用如下代码:

public class Program
{
    static void Main(string[] args)
    {
        // 创建三星工厂对象
        IPhoneFactory samsungFactory = new SamsungFactory();
        // 生产 GalaxyS10
        IPhone samsungPhone = samsungFactory.CreatePhone();
        // GalaxyS10 显示信息
        samsungPhone.Show();
        // 生产 GalaxyS10Display
        IDisplay samsungDisplay = samsungFactory.CreateDisplay();
        // GalaxyS10Display 显示信息
        samsungDisplay.Show();

        // 创建苹果工厂对象
        IPhoneFactory appleFactory = new AppleFactory();
        // 生产 iPhoneX
        IPhone applePhone = appleFactory.CreatePhone();
        // iPhoneX 显示信息
        applePhone.Show();
        // 生产 iPhoneXDisplay
        IDisplay appleDisplay = appleFactory.CreateDisplay();
        // iPhoneXDisplay 显示信息
        appleDisplay.Show();
    }
}

public interface IPhone
{
    void Show();
}

public class SamsungPhone : IPhone
{
    public void Show()
    {
        Console.WriteLine("This is a Samsung phone.");
    }
}

public class ApplePhone : IPhone
{
    public void Show()
    {
        Console.WriteLine("This is an Apple phone.");
    }
}

public interface IDisplay
{
    void Show();
}

public class SamsungDisplay : IDisplay
{
    public void Show()
    {
        Console.WriteLine("This is a Samsung display.");
    }
}

public class AppleDisplay : IDisplay
{
    public void Show()
    {
        Console.WriteLine("This is an Apple display.");
    }
}

public interface IPhoneFactory
{
    IPhone CreatePhone();
    IDisplay CreateDisplay();
}

public class SamsungFactory : IPhoneFactory
{
    public IPhone CreatePhone()
    {
        return new SamsungPhone();
    }

    public IDisplay CreateDisplay()
    {
        return new SamsungDisplay();
    }
}

public class AppleFactory : IPhoneFactory
{
    public IPhone CreatePhone()
    {
        return new ApplePhone();
    }

    public IDisplay CreateDisplay()
    {
        return new AppleDisplay();
    }
}

2. 结构型模式

适配器模式

适配器模式(Adapter Pattern)将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

例如,我们有一个使用220V电压的电视,但我们只有110V的电源,此时就需要将电源适配器中的110V电压转换为220V电压。则可以使用如下代码:

public class Program
{
    static void Main(string[] args)
    {
        // 使用电源适配器
        PowerAdapter adapter = new PowerAdapter();
        adapter.ChangeVoltage();
    }
}

public interface IPower
{
    void Use220V();
}

public class TV : IPower
{
    public void Use220V()
    {
        Console.WriteLine("使用220V电压");
    }
}

public class PowerAdapter
{
    private readonly IPower power;

    public PowerAdapter()
    {
        this.power = new TV();
    }

    public void ChangeVoltage()
    {
        Console.WriteLine("使用电源适配器");
        this.power.Use220V();
    }
}

3. 行为型模式

责任链模式

责任链模式(Chain of Responsibility Pattern)为解除请求的发送者和接收者之间的耦合,而将请求的处理者链式排列,将请求沿着这条链传递,直到有一个处理者能够处理它为止。

例如,我们在一个网站上购买商品时,会出现多种付款方式,如支付宝、微信、银联等,如果某个付款方式被拒绝,则会依次切换到下一个付款方式,直到订单被支付为止。则可以使用如下代码:

public class Program
{
    static void Main(string[] args)
    {
        // 创建支付方式
        PaymentHandler aliPayHandler = new AliPayHandler();
        PaymentHandler wechatPayHandler = new WechatPayHandler();
        PaymentHandler unionPayHandler = new UnionPayHandler();

        // 设置支付方式之间的顺序
        aliPayHandler.SetNextHandler(wechatPayHandler);
        wechatPayHandler.SetNextHandler(unionPayHandler);

        // 客户端输入购买商品的总金额和支付方式,通过支付方式进行支付
        Console.WriteLine("请输入购买商品的总金额:");
        decimal total = decimal.Parse(Console.ReadLine());
        Console.WriteLine("请选择支付方式:1.支付宝 2.微信支付 3.银联支付");
        int payType = int.Parse(Console.ReadLine());
        Payment request = new Payment { Total = total, PayType = (PayTypeEnum)payType };

        aliPayHandler.HandleRequest(request);
    }
}

public enum PayTypeEnum
{
    AliPay = 1,
    WechatPay = 2,
    UnionPay = 3
}

public class Payment
{
    public decimal Total { get; set; }
    public PayTypeEnum PayType { get; set; }
}

public abstract class PaymentHandler
{
    protected PaymentHandler nextHandler;

    public void SetNextHandler(PaymentHandler nextHandler)
    {
        this.nextHandler = nextHandler;
    }

    public abstract void HandleRequest(Payment request);
}

public class AliPayHandler : PaymentHandler
{
    public override void HandleRequest(Payment request)
    {
        if (request.PayType == PayTypeEnum.AliPay)
        {
            Console.WriteLine("使用支付宝支付了{0}元", request.Total);
        }
        else
        {
            if (nextHandler != null)
            {
                nextHandler.HandleRequest(request);
            }
        }
    }
}

public class WechatPayHandler : PaymentHandler
{
    public override void HandleRequest(Payment request)
    {
        if (request.PayType == PayTypeEnum.WechatPay)
        {
            Console.WriteLine("使用微信支付支付了{0}元", request.Total);
        }
        else
        {
            if (nextHandler != null)
            {
                nextHandler.HandleRequest(request);
            }
        }
    }
}

public class UnionPayHandler : PaymentHandler
{
    public override void HandleRequest(Payment request)
    {
        if (request.PayType == PayTypeEnum.UnionPay)
        {
            Console.WriteLine("使用银联支付支付了{0}元", request.Total);
        }
        else
        {
            if (nextHandler != null)
            {
                nextHandler.HandleRequest(request);
            }
        }
    }
}

四、结论

文章最后总结了C#中常见的23种设计模式,还提醒读者在实际应用中需要根据具体情况灵活使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#面向对象的23种设计模式介绍 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • sqlserver利用存储过程去除重复行的sql语句

    sqlserver利用存储过程去除重复行的SQL语句攻略: 创建存储过程 首先需要在SQL Server中创建存储过程,以下是示例代码: CREATE PROCEDURE RemoveDuplicateRows AS BEGIN SET NOCOUNT ON; SELECT DISTINCT * INTO #TempTable FROM YourTableN…

    C# 2023年6月2日
    00
  • C# 无限级分类的实现

    C# 无限级分类的实现 什么是无限级分类? 无限级分类又称为多级分类,是指一种基于树状结构的数据分类方法。其特点是可以不断的按照需求无限拓展分类层级。 实现无限级分类的步骤 第一步:建立分类表 首先我们需要建立一个分类表,在分类表中应包含以下几个重要字段: 字段 类型 描述 id int 分类编号,主键 name nvarchar 分类名称 parent_i…

    C# 2023年5月31日
    00
  • FileShare枚举的使用小结(文件读写锁)

    下面是关于FileShare枚举的使用小结(文件读写锁)的完整攻略: 1. FileShare枚举概述 FileShare枚举用于指定在打开文件时是否允许其他进程对该文件的访问。例如,当一个进程尝试打开一个文件时,如果该文件被另一个进程独占打开,则会发生访问冲突。 FileShare枚举提供了一种更细粒度的文件读写锁,可以根据不同的需求指定不同的文件访问权限…

    C# 2023年5月14日
    00
  • 解析C#网络编程中的Http请求

    解析C#网络编程中的Http请求可以分为以下几个步骤: 1. 构造HttpWebRequest对象 在C#网络编程中,我们使用HttpWebRequest对象来发起一次HTTP请求。构造HttpWebRequest对象需要指定请求的URL、请求方法等参数。下面是一个构造HttpWebRequest对象的示例代码: HttpWebRequest request…

    C# 2023年5月31日
    00
  • 正则基础之 \b 单词边界

    正则表达式中,\b 表示单词边界,常用于匹配单词或单词的开头和结尾。单词边界指的是一个单词与其他字符之间的分界点,通常是单词的开头或结束位置。 \b 的匹配规则如下: 如果 \b 出现在正则表达式的开头或结尾,则它匹配的是单词边界位置。 如果 \b 出现在正则表达式中间,则它匹配的是单词边界的位置,即左侧字符和右侧字符一个属于单词字符,一个不属于单词字符。 …

    C# 2023年6月7日
    00
  • C# 可空类型的具体使用

    C# 可空类型是一种特殊的数据类型,允许变量的值为空。这在处理一些场景时非常有用,例如数据库中某些字段允许为空值,或者某些函数的返回值可能为空。 可空类型的定义 在 C# 中,可空类型通过在数据类型后面添加一个问号(?)来定义,例如 int? 定义了一个可空的整数类型,其值可以为 null 或者整数值。 判断可空类型是否为 null 要判断一个可空类型变量是…

    C# 2023年5月31日
    00
  • 深入C#中get与set的详解

    深入C#中get与set的详解 在C#中,我们经常会定义属性来访问某个类的私有成员变量,其中get和set就是属性中最常用的关键字之一。本篇文章将对get和set进行详细讲解,包括其基本用法和使用注意事项。 get和set的基本用法 get和set是属性中最常用的关键字。属性可分为只读和可读写的两种,只读属性只包含get访问器,可读写属性则包含get和set…

    C# 2023年5月31日
    00
  • C# wpf 通过HwndHost渲染视频的实现方法

    在C# WPF中,可以使用HwndHost类来实现通过渲染视频的实现方法。HwndHost类允许将Win32窗口嵌入到WPF应用程序中,从而实现在WPF应用程序中渲染视频的效果。本文将提供详解如何使用HwndHost类实现通过渲染视频的完整攻略,包括如何创建HwndHost对象、如何设置Win32窗口句柄、如何处理HwndHost事件等。同时,本文还提供两个…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部