• C#设计模式——命令模式(Command Pattern)


    一、概述
    通常来说,“行为请求者”与“行为实现者”是紧耦合的。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这些情况下,将“行为请求者”与“行为实现者”解耦,实现二者之间的松耦合就至关重要。命令模式是解决这类问题的一个比较好的方法。
    二、命令模式
    命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
    命令模式的结构图如下

    Command定义了命令的接口
    ConcreteCommand实现Command接口,定义了具体的命令
    Client用于创建具体的命令并设定接收者
    Invoker要求Command执行相应的请求
    Receiver实施与执行一个请求,任何一个类都可能作为Receiver。
    三、示例
    假定要实现一个绘图系统,要求支持撤销功能,下面就用命令模式来实现这一需求。
    首先定义一个抽象的命令接口

    1 publicinterface IGraphCommand
    2 {
    3 void Draw();
    4 void Undo();
    5 }

    接着实现具体的绘图命令

    publicclass Line : IGraphCommand
    {
    private Point startPoint;
    private Point endPoint;
    public Line(Point start, Point end)
    {
    startPoint
    = start;
    endPoint
    = end;
    }

    publicvoid Draw()
    {
    Console.WriteLine(
    "Draw Line:{0} To {1}", startPoint.ToString(), endPoint.ToString());
    }

    publicvoid Undo()
    {
    Console.WriteLine(
    "Erase Line:{0} To {1}", startPoint.ToString(), endPoint.ToString());
    }
    }

    publicclass Rectangle : IGraphCommand
    {
    private Point topLeftPoint;
    private Point bottomRightPoint;
    public Rectangle(Point topLeft, Point bottomRight)
    {
    topLeftPoint
    = topLeft;
    bottomRightPoint
    = bottomRight;
    }

    publicvoid Draw()
    {
    Console.WriteLine(
    "Draw Rectangle: Top Left Point {0}, Bottom Right Point {1}", topLeftPoint.ToString(), bottomRightPoint.ToString());
    }

    publicvoid Undo()
    {
    Console.WriteLine(
    "Erase Rectangle: Top Left Point {0}, Bottom Right Point {1}", topLeftPoint.ToString(), bottomRightPoint.ToString());
    }
    }

    publicclass Circle : IGraphCommand
    {
    private Point centerPoint;
    privateint radius;
    public Circle(Point center, int radius)
    {
    centerPoint
    = center;
    this.radius = radius;
    }

    publicvoid Draw()
    {
    Console.WriteLine(
    "Draw Circle: Center Point {0}, Radius {1}", centerPoint.ToString(), radius.ToString());
    }

    publicvoid Undo()
    {
    Console.WriteLine(
    "Erase Circle: Center Point {0}, Radius {1}", centerPoint.ToString(), radius.ToString());
    }
    }

    然后再定义绘图类作为命令接收者

     1 publicclass Graphics
    2 {
    3 Stack<IGraphCommand> commands =new Stack<IGraphCommand>();
    4
    5 publicvoid Draw(IGraphCommand command)
    6 {
    7 command.Draw();
    8 commands.Push(command);
    9 }
    10
    11 publicvoid Undo()
    12 {
    13 IGraphCommand command = commands.Pop();
    14 command.Undo();
    15 }
    16 }

    最后看一下如何调用

     1 staticvoid Main(string[] args)
    2 {
    3 Line line =new Line(new Point(10, 10), new Point(100, 10));
    4 Rectangle rectangle =new Rectangle(new Point(20, 20), new Point(50, 30));
    5 Circle circle =new Circle(new Point(500, 500), 200);
    6
    7 Graphics graphics =new Graphics();
    8 graphics.Draw(line);
    9 graphics.Draw(rectangle);
    10 graphics.Undo();
    11 graphics.Draw(circle);
    12
    13 Console.ReadLine();
    14 }
  • 相关阅读:
    KVM 开启嵌套虚拟化
    我非要捅穿这 Neutron(三)架构分析与代码实现篇(基于 OpenStack Rocky)
    我非要捅穿这 Neutron(二)上层资源模型篇
    我非要捅穿这 Neutron(一)网络实现模型篇
    Cinder 架构分析、高可用部署与核心功能解析
    php学习笔记-echo输出html代码
    php学习笔记-echo怎么换行
    php学习笔记-echo的用法
    php学习笔记-php简单的语法入门
    sololearn这个app很不错
  • 原文地址:https://www.cnblogs.com/saville/p/2142754.html
Copyright © 2020-2023  润新知