首页 > 程序开发 > Web开发 > ASP.Net >

步步为营 .NET 设计模式学习笔记 九、Command(命令模式)

2011-04-14

概述 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现

概述

在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。这就是本文要说的Command模式。

意图

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。[GOF 《设计模式》]

结构图

<Design Pattern>Command模式结构图如下:

alt

图1 Command模式结构图

西游记中例子:玉帝传美猴王上天

命令模式不是新的发明,在美猴王大闹天宫之前就有了。那时玉帝命令太白金星召美猴王上天:"金星径入(水帘洞)当中,面南立定道:我是西方太白金星,奉玉帝招安圣旨,下界请你上大,拜受仙录。"玉帝是系统的客户端,太白金星是命令的发出者,猴王是命令的接收者,圣旨就是命令。玉帝的这一道命令就是要求猴王到上界报到。玉帝只管发出命令,而不管命令是怎样传达到美猴王的。太白金星负责将圣旨传到,可是美猴王怎么执行圣旨、何时执行圣旨是美猴王自己的事。果不然,个久美猴王就大闹了天宫。

这个模拟系统的设计如下:

生活中的例子

Command模式将一个请求封装为一个对象,从而使你可以使用不同的请求对客户进行参数化。用餐时的账单是Command模式的一个例子。服务员接受顾客的点单,把它记在账单上封装。这个点单被排队等待烹饪。注意这里的"账单"是不依赖于菜单的,它可以被不同的顾客使用,因此它可以添入不同的点单项目。

alt

图2 使用用餐例子的Command模式对象图

示例用例结构图:

手机操作系统包括开机、关机、打电话、挂电话、发短信和删除短信功能,其实这就是一个命令模式,类结构示意图如下:

image

先创建接口ICommand.cs:

    public interface ICommand
    {
        /// <summary>
        /// 执行命令
        /// </summary>
        string Execute();
        /// <summary>
        /// 撤消命令
        /// </summary>
        string UnExecute();
    }

再创建SystemCommand.cs:

  public  class SystemCommand
    {
       public string StartUp()
       {
           return "手机开机";
       }
       public string ShutDown()
       {
           return "手机关机";
       }
       public string SendSMS()
       {
           return "发短信";
       }
       public string RemoveSMS()
       {
           return "删短信";
       }
       public string CallPhone()
       {
           return "打电话";
       }
       public string RingOff()
       {
           return "挂电话";
       }
    }

再创建MobileSystem.cs:

 public abstract class MobileSystem :ICommand
    {
        private SystemCommand mobileCommand;
        public SystemCommand MobileCommand
        {
            get 
            {
                return mobileCommand;
            }
            set 
            {
                mobileCommand = value;
            }
        }
        public MobileSystem(SystemCommand command)
        {
            this.mobileCommand = command;
        }
        #region ICommand 成员
        public abstract string Execute();
       public abstract string UnExecute();
        #endregion
    }

再创建StartUp.cs:

   public  class StartUp :MobileSystem
   {
       #region MobileSystem 成员
       public override string  Execute()
        {
            return MobileCommand.StartUp();
        }
        public override string UnExecute()
        {
            return MobileCommand.ShutDown();
        }
        #endregion
        public StartUp(SystemCommand command)
            : base(command)
        { }
    }

再创建Call.cs:

 public class Call : MobileSystem
    {
        #region MobileSystem 成员
        public override string Execute()
        {
            return MobileCommand.CallPhone();
        }
        public override string UnExecute()
        {
            return MobileCommand.RingOff();
        }
        #endregion
        public Call(SystemCommand command)
            : base(command)
        { }
    }

再创建SMS.cs:

    public class SMS : MobileSystem
    {
        #region MobileSystem 成员
        public override string Execute()
        {
            return MobileCommand.SendSMS();
        }
        public override string UnExecute()
        {
            return MobileCommand.RemoveSMS();
        }
        #endregion
        public SMS(SystemCommand command)
            : base(command)
        { }
    }

再创建MobileServer.cs:

  public class MobileServer : ICommand
    {
       private MobileSystem mobileSystem;
       public MobileServer(MobileSystem system)
       {
           this.mobileSystem = system;
       }
       public string Execute()
       {
         return  mobileSystem.Execute();
       }
       public string UnExecute()
       {
           return mobileSystem.UnExecute();
       }
    }

最后再调用:

 public partial class Run : Form
    {
        public Run()
        {
            InitializeComponent();
        }
        private void btnRun_Click(object sender, EventArgs e)
        {
            SystemCommand command = new SystemCommand();
            MobileServer server = new MobileServer(new StartUp(command));
            rtbResult.AppendText(server.Execute() + "
");
            rtbResult.AppendText(server.UnExecute() + "
");
            server = new MobileServer(new Call(command));
            rtbResult.AppendText(server.Execute() + "
");
            rtbResult.AppendText(server.UnExecute() + "
");
            server = new MobileServer(new SMS(command));
            rtbResult.AppendText(server.Execute() + "
")		
相关文章
最新文章
热点推荐