命令模式 The Command Pattern

命令模式——“请求”封装成对象,以便使用不同的请求,队列或者日志来参数化其它对象。命令模式也支持可撤消的操作。(摘自《Head First Design Patterns》)
以下是自已用VS画了一个简图:
创建命令接口:
interface ICommand

    {

        void Execute();



        void Undo();

    }
实现三个命令:
class AttackCommand : ICommand

    {

        #region Command 成员



        public void Execute()

        {

            Console.WriteLine("攻击");

        }



        public void Undo()

        {

            Console.WriteLine("撤消攻击");

        }



        #endregion

    }

class RetreatCommand : ICommand

    {

        #region Command 成员



        public void Execute()

        {

            Console.WriteLine("撤退");

        }



        public void Undo()

        {

            Console.WriteLine("撤消撤退");

        }



        #endregion

    }



class NoCommand : ICommand

    {

        #region ICommand 成员



        public void Execute()

        {

            

        }



        public void Undo()

        {

            

        }



        #endregion

    }
其中空命令为了初始化使用,不必判断NULL了。创建一个司令官,用来发布命令:
class Commander

    {

        private ICommand UndoCommand = new NoCommand();

    

        public void SetCommand(ICommand command)

        {

            command.Execute();

            UndoCommand = command;

        }



        public void UndoLastCommand()

        {

            UndoCommand.Undo();

            UndoCommand = new NoCommand();

        }

    }
测试一下:
Commander commander = new Commander();

            AttackCommand attackCommand = new AttackCommand();

            RetreatCommand retreatCommand = new RetreatCommand();

            commander.SetCommand(attackCommand);

            commander.UndoLastCommand();

            commander.SetCommand(retreatCommand);

            commander.UndoLastCommand();

            commander.SetCommand(attackCommand);

            commander.SetCommand(retreatCommand);

            commander.UndoLastCommand();

            commander.UndoLastCommand();//程序只实了一次撤消,因此这里的第二次撤消没有作用,用户可以创建撤消命令数组来存储实现多次撤消。
输出结果:
攻击
撤消攻击
撤退
撤消撤退
攻击
撤退
撤消撤退
在以前的观察者模式中,使用了发布命令,但是没用应用命令模式,现在结合命令模式重新改写一下以前的观察者模式:
下面是用VS画的一个简图:
其中原本用的接口改成了抽象类,为了简化一下代码,这里主要是为了我自己的这个例子。
/// <summary>

    /// 主题对象接口

    /// </summary>

    public interface ISubject

    {

        List<Observer> Observers

        {

            get;

            set;

        }



        void RegisterObserver(Observer observer);



        void RemoveObserver(Observer observer);



        void NotifyObservers();

    }



/// <summary>

    /// 观察者基类

    /// </summary>

    public abstract class Observer

    {

        public abstract void Update(Command command);



        #region = Name =



        private string _name;



        public string Name

        {

            get { return _name; }

            set { _name = value; }

        }



        #endregion



        #region = AttackSlogan =



        private string _attackslogan;



        public string AttackSlogan

        {

            get { return _attackslogan; }

            set { _attackslogan = value; }

        }



        #endregion



        #region = RetreatSlogan =



        private string _retreatslogan;



        public string RetreatSlogan

        {

            get { return _retreatslogan; }

            set { _retreatslogan = value; }

        }



        #endregion

    }



/// <summary>

    /// 斧头小队--观察者

    /// </summary>

    public class AxeTeam : Observer 

    {

        #region Observer 成员

        



        public AxeTeam()

        {

            this.Name = "斧头小队";

            this.AttackSlogan = "用斧头攻击,势死如归!";

            this.RetreatSlogan = "坚守阵地,死也不放弃!";

        }



        public override void Update(Command command)

        {

            command.Observer = this;

            command.Execute();

        }



        #endregion

    }



/// <summary>

    /// 弓箭手小队--观察者

    /// </summary>

    public class BowAndArrowTeam : Observer 

    {

        #region Observer 成员

     



        public BowAndArrowTeam()

        {

            this.Name = "弓箭手小队";

            this.AttackSlogan = "弓箭手掩护,退后十步,射箭!";

            this.RetreatSlogan = "边撤退,边掩护斧头小队!";

        }



        public override void Update(Command command)

        {

            command.Observer = this;

            command.Execute();

        }



        #endregion

    }



/// <summary>

    /// 匕首小队--观察者

    /// </summary>

    public class KnifeTeam : Observer

    {

        #region Observer 成员



       



        public KnifeTeam()

        {

            this.Name = "匕首小队";

            this.AttackSlogan = "匕首攻击,打不过就跑!";

            this.RetreatSlogan = "快撤啊,我军大势已去!";

        }



        public override void Update(Command command)

        {

            command.Observer = this;

            command.Execute();

        }



        #endregion

    }



/// <summary>

    /// 司令官---主题对象以及发布命令

    /// </summary>

    public class Commander : ISubject

    {

        #region ISubject 成员

        private List<Observer> _observers;

        public List<Observer> Observers

        {

            get

            {

                return _observers;

            }

            set

            {

                _observers = value;

            }

        }



        public Command Command = new NoCommand();



        public Commander()

        {

            _observers = new List<Observer>();

        }



        public void RegisterObserver(Observer observer)

        {

            this.Observers.Add(observer);

        }



        public void RemoveObserver(Observer observer)

        {

            this.Observers.Remove(observer);

        }



        public void NotifyObservers()

        {

            foreach (Observer observer in this.Observers)

            {

                observer.Update(this.Command);

            }

        }



        #endregion



        public void SetCommand(Command command)

        {

            this.Command = command;

            NotifyObservers();

        }

    }



 /// <summary>

    /// 命令基类

    /// </summary>

    public abstract class Command

    {

        #region = Observer =



        private Observer _observer;



        public Observer Observer

        {

            get { return _observer; }

            set { _observer = value; }

        }



        #endregion

    

        public abstract void Execute();

    }



/// <summary>

    /// 攻击命令

    /// </summary>

    class AttackCommand : Command

    {

        



        #region Command 成员



        public override void Execute()

        {

            Console.WriteLine(string.Format("{0}:{1}", this.Observer.Name, this.Observer.AttackSlogan));

        }



        #endregion



    }



/// <summary>

    /// 撤退命令

    /// </summary>

    class RetreatCommand : Command

    {

        

        #region Command 成员



        public override void Execute()

        {

            Console.WriteLine(string.Format("{0}:{1}", this.Observer.Name, this.Observer.RetreatSlogan));

        }



        #endregion

    }



/// <summary>

    /// 空命令

    /// </summary>

    class NoCommand : Command

    {

        

        #region Command 成员



        public override void Execute()

        {



        }



        #endregion

    }





测试一下:
//实例化司令官和三个小队

            Commander commander = new Commander();

            AxeTeam axe = new AxeTeam();

            BowAndArrowTeam baa = new BowAndArrowTeam();

            KnifeTeam knife = new KnifeTeam();

            AttackCommand attackCommand = new AttackCommand();

            RetreatCommand retreatCommand = new RetreatCommand();



            //注册观察者

            commander.RegisterObserver(axe);

            commander.RegisterObserver(baa);

            commander.RegisterObserver(knife);

            //司令官下命令

            commander.SetCommand(attackCommand);

            commander.SetCommand(retreatCommand);

            //匕首小队怕死,从军队中删除

            Console.WriteLine("匕首小队怕死,从军队中删除");

            commander.RemoveObserver(knife);

            //司令官再次下命令

            commander.SetCommand(attackCommand);

            commander.SetCommand(retreatCommand);
观察者模式和命令模式已经结到一起,输出结果:
斧头小队:用斧头攻击,势死如归!
弓箭手小队:弓箭手掩护,退后十步,射箭!
匕首小队:匕首攻击,打不过就跑!
斧头小队:坚守阵地,死也不放弃!
弓箭手小队:边撤退,边掩护斧头小队!
匕首小队:快撤啊,我军大势已去!
匕首小队怕死,从军队中删除
斧头小队:用斧头攻击,势死如归!
弓箭手小队:弓箭手掩护,退后十步,射箭!
斧头小队:坚守阵地,死也不放弃!
弓箭手小队:边撤退,边掩护斧头小队! ------------------------- 至此,全部介结完毕,有错误之处还请大家指出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值