C#设计模式之职责链模式示例详解

C#设计模式之职责链模式示例详解

什么是职责链模式

职责链模式是一种行为型模式,它能够将一个请求沿着多个对象链状传递,直到有一个对象处理该请求为止。这样的设计模式可以避免请求发送者与接收者之间的耦合,使得多个对象都有可能接收请求并处理它。

职责链模式的结构

这种模式通常包含一个抽象的处理者类,多个具体的处理者类,每个处理者类都包括一个指向下一个处理者的引用,一般情况下,责任链中的处理者对象都包含相同类型的操作。

职责链模式的示例

下面,我们将使用一些实际的例子来展示职责链模式的用法。首先,我们考虑一个文件上传的场景。在这种情况下,我们只允许上传特定类型的文件,例如图片、文本、音频、视频等等。

public abstract class UploadHandler
{
    protected UploadHandler _nextHandler;

    public void SetNextHandler(UploadHandler handler)
    {
        this._nextHandler = handler;
    }

    public abstract bool Handle(string fileType);
}

我们定义了一个抽象的上传处理者类UploadHandler,其中包括一个指向下一个处理者的引用,还有一个抽象的Handle方法用于处理上传的文件。下面为我们实现具体的上传处理者类。

public class ImageUploadHandler : UploadHandler
{
    public override bool Handle(string fileType)
    {
        if(fileType == "jpg" || fileType == "png")
        {
            Console.WriteLine("处理了图片文件!");
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(fileType);
        }
        Console.WriteLine("不支持的文件类型!");
        return false;
    }
}

public class TextUploadHandler : UploadHandler
{
    public override bool Handle(string fileType)
    {
        if(fileType == "txt" || fileType == "doc")
        {
            Console.WriteLine("处理了文本文件!");
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(fileType);
        }
        Console.WriteLine("不支持的文件类型!");
        return false;
    }
}

public class AudioUploadHandler : UploadHandler
{
    public override bool Handle(string fileType)
    {
        if(fileType == "mp3" || fileType == "wav")
        {
            Console.WriteLine("处理了音频文件!");
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(fileType);
        }
        Console.WriteLine("不支持的文件类型!");
        return false;
    }
}

public class VideoUploadHandler : UploadHandler
{
    public override bool Handle(string fileType)
    {
        if(fileType == "mp4" || fileType == "avi")
        {
            Console.WriteLine("处理了视频文件!");
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(fileType);
        }
        Console.WriteLine("不支持的文件类型!");
        return false;
    }
}

我们实现了四个不同类型的上传处理者类,每个类都重写了Handle方法,用于检查文件类型并处理上传的文件。如果有下一个处理者,则向下传递,否则返回不支持的文件类型。

最后,我们将实现一个用于测试的客户端类。

static void Main(string[] args)
{
    ImageUploadHandler imageHandler = new ImageUploadHandler();
    TextUploadHandler textHandler = new TextUploadHandler();
    AudioUploadHandler audioHandler = new AudioUploadHandler();
    VideoUploadHandler videoHandler = new VideoUploadHandler();

    imageHandler.SetNextHandler(textHandler);
    textHandler.SetNextHandler(audioHandler);
    audioHandler.SetNextHandler(videoHandler);

    Console.WriteLine(imageHandler.Handle("png"));
    Console.WriteLine(imageHandler.Handle("doc"));
    Console.WriteLine(imageHandler.Handle("mp3"));
    Console.WriteLine(imageHandler.Handle("mp4"));
    Console.WriteLine(imageHandler.Handle("xlsx"));
}

在这个测试客户端中,我们首先创建了四个上传处理者类的实例。然后,我们设置它们的处理顺序,并且将第一个处理者传递给客户端。最后,我们将测试多个文件的上传类型,每个文件都会经过一个处理者并返回结果,如果某个文件类型没有被处理,则会返回不支持的文件类型。

另一个职责链模式的示例

职责链模式的另一个示例是实现在线支付的场景。在这个场景中,我们需要使用多个支付方式,例如信用卡、支付宝、微信支付、银行转账等等。

abstract class PaymentHandler
{
    protected PaymentHandler _nextHandler;

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

    public abstract bool Handle(double amount);
}

我们定义了一个抽象的支付处理者类PaymentHandler,其中包括一个指向下一个处理者的引用,还有一个抽象的Handle方法用于处理支付请求。下面为我们实现具体的支付处理者类。

public class CreditCardHandler : PaymentHandler
{
    public override bool Handle(double amount)
    {
        if(amount <= 1000)
        {
            Console.WriteLine("使用信用卡支付了 {0} 元", amount);
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(amount);
        }
        Console.WriteLine("支付金额过大!");
        return false;
    }
}

public class AlipayHandler : PaymentHandler
{
    public override bool Handle(double amount)
    {
        if(amount <= 500)
        {
            Console.WriteLine("使用支付宝支付了 {0} 元", amount);
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(amount);
        }
        Console.WriteLine("支付金额过大!");
        return false;
    }
}

public class WechatPayHandler : PaymentHandler
{
    public override bool Handle(double amount)
    {
        if(amount <= 300)
        {
            Console.WriteLine("使用微信支付了 {0} 元", amount);
            return true;
        }
        if(this._nextHandler != null)
        {
            return this._nextHandler.Handle(amount);
        }
        Console.WriteLine("支付金额过大!");
        return false;
    }
}

public class BankTransferHandler : PaymentHandler
{
    public override bool Handle(double amount)
    {
        Console.WriteLine("使用银行转账支付了 {0} 元", amount);
        return true;
    }
}

我们实现了四个不同类型的支付处理者类,每个类都重写了Handle方法,用于检查支付金额并处理支付请求。如果有下一个处理者,则向下传递,否则返回支付金额过大。

最后,我们将实现一个用于测试的客户端类。

static void Main(string[] args)
{
    CreditCardHandler creditCardHandler = new CreditCardHandler();
    AlipayHandler alipayHandler = new AlipayHandler();
    WechatPayHandler wechatPayHandler = new WechatPayHandler();
    BankTransferHandler bankTransferHandler = new BankTransferHandler();

    creditCardHandler.SetNextHandler(alipayHandler);
    alipayHandler.SetNextHandler(wechatPayHandler);
    wechatPayHandler.SetNextHandler(bankTransferHandler);

    Console.WriteLine(creditCardHandler.Handle(100));
    Console.WriteLine(creditCardHandler.Handle(600));
    Console.WriteLine(creditCardHandler.Handle(400));
    Console.WriteLine(creditCardHandler.Handle(2000));
}

在这个测试客户端中,我们首先创建了四个支付处理者类的实例。然后,我们设置它们的处理顺序,并且将第一个处理者传递给客户端。最后,我们将测试多个支付金额,每个支付请求都会经过一个处理者并返回结果,如果某个支付金额过大,则会返回支付金额过大。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#设计模式之职责链模式示例详解 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法

    下面是详细讲解“Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法”的完整攻略: 新建Visual Studio项目 在Visual Studio中新建一个C++项目,选择“空项目”。 添加DLL库文件 将需要引用的DLL库文件(或者库文件夹)拷贝到项目文件夹中,并在Visual Studio中将其添加到项目中。右键项目,选…

    C# 2023年6月7日
    00
  • 基于John Carmark密码详解

    基于John Carmack密码详解 什么是John Carmack密码? John Carmack密码,也称为“DooM3密码”,是由游戏开发者John Carmack在2004年所创造的密码。这种密码的特点在于:使用了MD5哈希加密算法,并且还有一些特殊的操作。 John Carmack密码的组成 John Carmack密码由以下几个部分组成: 一个固…

    C# 2023年6月7日
    00
  • C#事件(event)使用方法详解

    C#事件(event)使用方法详解 在C#语言中,事件(event)是一种能够向外界传递消息并触发特定操作的机制。本文将详细讲解C#事件的基本概念、使用方法和注意事项等内容,帮助读者更好的掌握事件处理。 基本概念 事件是一种特殊的委托类型,它能够在对象状态发生变化时,向监听者发送信号并触发相应操作。事件通常包含以下几个要素: 事件源:触发事件的对象。 事件参…

    C# 2023年5月31日
    00
  • 外键拆分手记

    我习惯性使用OData,它的$expand与层级查询非常好用,这个功能非常依赖于数据库的导航属性,也就是外键结构。最近想着把一个单体的系统拆分为多个小系统,首先需要处理外键依赖的问题。 多个服务各自有各自的数据库,数据库层面并不互通,也就无法使用外键约束。 我使用EF Core来描述数据库的结构,有两个实体类如下: public class AD_Insec…

    C# 2023年4月27日
    00
  • C#日历样式的下拉式计算器实例讲解

    下面我来详细讲解一下“C#日历样式的下拉式计算器实例讲解”的完整攻略。 一、准备工作 在开始之前,我们需要完成以下准备工作: 安装好Visual Studio开发环境 创建一个Windows Froms应用程序项目 在表单中添加控件:日历控件、文本框控件、下拉框控件、按钮控件等 二、编写代码 1. 日历控件的使用 首先,我们需要使用日历控件来获取日期。在窗体…

    C# 2023年6月6日
    00
  • 怎么利用c#修改services的Startup type

    要利用C#修改Windows服务的启动类型(Startup type),可以使用.NET Framework下的ServiceController和ServiceType类。步骤如下: 步骤一:添加引用 在项目中添加System.ServiceProcess引用。 步骤二:获取服务 使用ServiceController类获取要修改的服务,可以用服务名称或服…

    C# 2023年6月6日
    00
  • C# 3DES加密详解

    首先,我们先来了解一下3DES加密算法。 3DES即Triple DES,是DES加密算法的加强版。在3DES加密算法中,数据被加密的过程其实就是三次DES加密的过程,即使用三个不同的密钥对数据进行加密。 下面来介绍一下C#中的3DES加密操作。 算法说明 在C#中,我们使用System.Security.Cryptography命名空间中的TripleDE…

    C# 2023年6月8日
    00
  • C# 实现winform软件最小化到系统托盘,开机自启动

    C# 实现winform软件最小化到系统托盘,开机自启动   问题描述   用户的电脑是win7系统,应用系统在用户电脑上运行时部分功能需要访问注册表,但是使用这些功能时会提示用户没有权限访问注册表。原因分析   win7及后续高版本系统对用户的权限控制比较严,就算用户的权限较高,但用户启动程序时默认还是以普通用户的权限启动,因此造成应用程序访问操作系统相关…

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