C# 一分钟浅谈:命令模式与职责链模式

简介: 【10月更文挑战第16天】本文介绍了命令模式和职责链模式两种行为设计模式。命令模式将请求封装成对象,支持可撤销操作;职责链模式将请求沿处理者链传递,支持动态添加或删除处理者。文章通过C#代码示例详细解释了这两种模式的核心组件、优点、缺点及常见问题,并提供了如何避免这些问题的建议。

在软件设计模式中,命令模式和职责链模式都是非常实用的设计模式,它们可以帮助我们构建更加灵活和可扩展的应用程序。本文将从基础概念出发,逐步深入探讨这两种模式,并通过具体的C#代码示例来帮助理解。
image.png

命令模式

概念

命令模式是一种行为设计模式,它将请求封装成对象,从而使你可以用不同的请求、队列或者请求日志参数化其他对象。命令模式也支持可撤销的操作。

核心组件

  • Command(命令接口) :声明执行操作的接口。
  • ConcreteCommand(具体命令) :实现命令接口,定义与接收者相关的绑定操作。
  • Receiver(接收者) :知道如何实施与执行一个请求相关的操作。
  • Invoker(调用者) :要求命令对象执行请求。
  • Client(客户端) :创建具体命令对象并设置其接收者。

优点

  • 解耦:发送者与接收者解耦。
  • 扩展性:可以很容易地增加新的命令。
  • 支持撤销操作:命令对象可以存储状态以便撤销操作。

缺点

  • 类膨胀:每一个命令都需要一个具体的类来实现。

示例代码

// 命令接口
public interface ICommand
{
   
    void Execute();
}

// 具体命令
public class LightOnCommand : ICommand
{
   
    private readonly Light _light;

    public LightOnCommand(Light light)
    {
   
        _light = light;
    }

    public void Execute()
    {
   
        _light.TurnOn();
    }
}

// 接收者
public class Light
{
   
    public void TurnOn()
    {
   
        Console.WriteLine("Light is on");
    }
}

// 调用者
public class RemoteControl
{
   
    private ICommand _command;

    public void SetCommand(ICommand command)
    {
   
        _command = command;
    }

    public void PressButton()
    {
   
        _command.Execute();
    }
}

// 客户端
class Program
{
   
    static void Main(string[] args)
    {
   
        var light = new Light();
        var lightOnCommand = new LightOnCommand(light);
        var remoteControl = new RemoteControl();

        remoteControl.SetCommand(lightOnCommand);
        remoteControl.PressButton(); // 输出: Light is on
    }
}

常见问题与易错点

  • 过度使用命令模式:并不是所有的情况都适合使用命令模式,过度使用会导致类的膨胀。
  • 命令对象的状态管理:如果命令对象需要维护状态,需要小心管理,避免内存泄漏。

如何避免

  • 合理评估需求:在决定是否使用命令模式时,评估其带来的好处是否大于增加的复杂度。
  • 使用泛型:可以通过泛型来减少具体命令类的数量。

职责链模式

概念

职责链模式是一种行为设计模式,它允许你将请求沿着处理者链进行发送。收到请求后,每个处理者都可以处理请求或将其传递给链中的下一个处理者。

核心组件

  • Handler(处理者接口) :声明处理请求的方法。
  • ConcreteHandler(具体处理者) :处理请求或将其传递给下一个处理者。
  • Client(客户端) :创建处理者对象并发起请求。

优点

  • 解耦:发送者和接收者解耦。
  • 灵活性:可以动态地添加或删除处理者。

缺点

  • 调试困难:由于请求可能经过多个处理者,调试时可能比较困难。
  • 性能问题:如果链过长,可能会导致性能下降。

示例代码

// 处理者接口
public abstract class Handler
{
   
    protected Handler _nextHandler;

    public void SetNext(Handler nextHandler)
    {
   
        _nextHandler = nextHandler;
    }

    public abstract void HandleRequest(int request);
}

// 具体处理者
public class ConcreteHandler1 : Handler
{
   
    public override void HandleRequest(int request)
    {
   
        if (request >= 0 && request < 10)
        {
   
            Console.WriteLine($"ConcreteHandler1 handled request {request}");
        }
        else if (_nextHandler != null)
        {
   
            _nextHandler.HandleRequest(request);
        }
    }
}

public class ConcreteHandler2 : Handler
{
   
    public override void HandleRequest(int request)
    {
   
        if (request >= 10 && request < 20)
        {
   
            Console.WriteLine($"ConcreteHandler2 handled request {request}");
        }
        else if (_nextHandler != null)
        {
   
            _nextHandler.HandleRequest(request);
        }
    }
}

// 客户端
class Program
{
   
    static void Main(string[] args)
    {
   
        var handler1 = new ConcreteHandler1();
        var handler2 = new ConcreteHandler2();

        handler1.SetNext(handler2);

        handler1.HandleRequest(5);  // 输出: ConcreteHandler1 handled request 5
        handler1.HandleRequest(15); // 输出: ConcreteHandler2 handled request 15
        handler1.HandleRequest(25); // 输出: 无输出,因为没有处理者处理 25
    }
}

常见问题与易错点

  • 链的终止:确保链的最后一个处理者能够正确处理未被处理的请求,避免无限循环。
  • 性能问题:如果链过长,可能会导致性能下降。

如何避免

  • 明确链的终止条件:确保每个处理者都有明确的处理逻辑,并且链的最后一个处理者能够处理未被处理的请求。
  • 优化链的长度:根据实际需求合理设计链的长度,避免不必要的处理者。

总结

命令模式和职责链模式都是行为设计模式,它们各自有不同的应用场景和优缺点。通过本文的介绍和示例代码,希望读者能够更好地理解和应用这两种设计模式,从而构建更加灵活和可扩展的应用程序

目录
相关文章
|
C# 数据安全/隐私保护
C#机房重构-修改密码之职责链模式+反射
C#机房重构-修改密码之职责链模式+反射
62 0
|
设计模式 C#
【设计模式】C#实现职责链模式
责任链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
|
C#
C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】
原文:C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】 一、引言   今天我们开始讲“行为型”设计模式的第八个模式,该模式是【职责链模式】,英文名称是:Chain of Responsibility Pattern。
1276 0
|
C# 设计模式 程序员
C#设计模式(15)——命令模式(Command Pattern)
原文:C#设计模式(15)——命令模式(Command Pattern) 一、前言   之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的技术水平,因为对于一个功能的实现,高级工程师和初级工程师一样都会实现,但是区别在于它们实现功能的可扩展和可维护性,也就是代码的是否“优美”、可读。
1154 0
|
存储 C# 设计模式
C# 命令模式
一、命令模式:         将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 ——《设计模式》 二、模式结构: Command:         定义命令的接口,声明执行的方法。 ConcreteCommand:         命令接口实现对象,是“虚”的实现;通常会
1079 0
|
C#
乐在其中设计模式(C#) - 命令模式(Command Pattern)
原文:乐在其中设计模式(C#) - 命令模式(Command Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd 介绍 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。
1012 0
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
34 3
|
1月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
47 4
|
3月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
50 2