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

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

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

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

接着实现具体的绘图命令

复制代码
    public class Line : IGraphCommand
    {
        private Point startPoint;
        private Point endPoint;
        public Line(Point start, Point end)
        {
            startPoint = start;
            endPoint = end;
        }

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

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

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

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

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

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

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

        public void Undo()
        {
            Console.WriteLine("Erase Circle: Center Point {0},  Radius {1}", centerPoint.ToString(), radius.ToString());
        }
    }
复制代码

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

复制代码
 1     public class Graphics
 2     {
 3         Stack<IGraphCommand> commands = new Stack<IGraphCommand>();
 4 
 5         public void Draw(IGraphCommand command)
 6         {
 7             command.Draw();
 8             commands.Push(command);
 9         }
10 
11         public void Undo()
12         {
13             IGraphCommand command = commands.Pop();
14             command.Undo();
15         }
16     }
复制代码

最后看一下如何调用

复制代码
 1     static void 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     }   
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值