大话设计-命令模式

每个模式都在传递着一种与众不同的编程理念。每次都仿佛是站在巨人的上,一步步的学习,积土成山。

最近学习了命令模式,喜欢它很简单:开篇从小菜大鸟吃肉串谈起,慢慢的吸引着我的注意力,因为感兴趣,所以有了进一步的研究。

【命令模式】

1.定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

2.如图所示:

         

很简单,抽象出来命令类,然后定义一个实现命令类的接口。与此有直接联系的是命令执行者和命令发出者,但是根据弱耦合原则,具体的命令执行者和命令的发出者之间没有直接的关联,Invoker类实现了命令的上传下达,是命令得以实现的关键因素。

3.个人理解

代码总是在需求的变化中不断优化的。

At first:大鸟和小菜去街边小摊上吃烧烤,大家也都亲历过在大街上买烤串:消费者提出消费请求-烧烤老板根据需求执行烧烤动作-一手交钱一手交货。这对于小批量的消费人群来说,没有什么不合理的地方,但是随着消费人群的扩大,消费量的增加,就会给烧烤老板带来一定的压力,如果老板足够精明还好,要是记性不好的话,就会造成不必要的损失。拽个设计模式术语:这叫做耦合性太强。

 //烤肉串者
    public class Barbecure
    {
        //烤羊肉
        public void BackMutton()
        {
            Console.WriteLine("烤羊肉串!");
        }
        //烤鸡翅
        public void BakeChickenWing()
        {
            Console.WriteLine("烤鸡翅");
        }

    }

then:【烧烤店VS烧烤摊】因为不太满意烧烤摊老板的服务,小菜建议去烧烤店吃,在这里就不一样了,烧烤店里有专门的服务人员来记录顾客需求并且发出消费通知,形成日志记录各种需求,达到有迹可循的目的,不会因为记不清楚而算错帐了。于是形成了如下需求模式——松耦合设计

  //抽象命令类
    public abstract class Command
    {
        protected Barbecuer receiver;
        public Command(Barbecuer receiver)
        {
            this.receiver = receiver;
        }

        abstract public void ExcuteCommand();
    }
 //服务员类
    public class Waiter
    {
        private Command command;
        public void SetOrder(Command command)
        {
            this.command = command;

        }
        public void Notify()
        {
            command.ExcuteCommand();
        }
}

抽象出来了服务员类(用于记录顾客需求信息,形成日志资料),服务员要做的是:当顾客点完餐后通知厨房去做。这样就避免了顾客直接与烧烤老板的联系,也就减少了不必要的纠纷。但是,这样问题就又来了,如果供应不充足,在这里需要有一个很长时间的信息确认时间,也就是说物料不充足时,不应该是顾客来判断是否还有,应该是服务员提供物料供应信息,这样才算是“全心全意为人民服务”——优化的松耦合设计

Today:人性化的服务满足了消费者的需求。继续对代码进行优化设计:将物料供应信息全部提供给服务员,这样在顾客点餐的时候不会出现不必要的麻烦。使用命令模式可以很好地解决这个问题。

 //服务员类
    public class Waiter
    {
        private IList<Command> orders = new List<Command>();
        //设置订单
        public void SetOrder(Command command)
        {
            if (command.ToString() == "命令模式.BakeChikenWingCommand")
            {
                Console.WriteLine("服务员:鸡翅没有了,要点别的吧。");
            }
            else
            {
                orders.Add(command);
                Console.WriteLine ("增加订单:"+command .ToString ()+"时间:"+DateTime .Now .ToString ());
            }
        }
        //取消订单
        public void CancelOrder(Command command)
        {
            orders.Remove(command);
            Console.WriteLine("取消订单:" + command.ToString() + "时间:" + DateTime.Now.ToString());
        }

        //通知全部执行
        public void Notify()
        {
            foreach (Command cmd in orders)
            {
                cmd.ExcuteCommand();
            }
        }

    }
这样,就万事俱备啦。

总结一下命令模式的优点:

1.能比较容易的设计一个命令队列;
2.在需要的情况下,可以比较容易的命令记入日志
3.允许接收请求的一方决定是否要否决请求
4.可以容易地实现对请求的撤销和重做;
5.由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
6.命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。

【温馨提示】

敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能,如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复等功能是,把原来的代码重构为命令模式才有意义。

【学习感受】

最近一直在学习大话设计模式,我也说不清怎样算是学懂了、学透了。每次新接触一种设计模式,总是会先看一遍课本,理解了模式的思想之后再去实现书本上的例子,能大致理解模式的思想,但是对于客户端的代码实现却觉得有点艰难,可能是理论还没有联系实践的缘故,难免有一些茫然不知所措。还是先土豆土豆炖着吧,慢慢的总是会大彻大悟的。。。




posted @ 2014-11-26 20:04  幻想泡沫  阅读(171)  评论(0编辑  收藏  举报