码迷,mamicode.com
首页 > 其他好文 > 详细

码农小汪-设计模式之-命令模式

时间:2016-04-17 23:10:04      阅读:249      评论:0      收藏:0      [点我收藏+]

标签:

大话设计模式的例子讲的非常的好,理解起来也方便!有时候忘了。想到这些特殊的例子感觉就是特别爽。

烤羊肉串带来的思考!
路边摊羊肉串:
老板,我这里排的比较先啊,我最先给钱。老板这个没有熟啊。我的是 辣的啊!老板没有放盐啊!场面混乱,已经分不清谁是谁的啊,人太多了。烤肉的质量也受到了影响,心情不好也就不好啊。烤肉的人心情受到了顾客的影响。
店面的烤肉
服务员,给我来两串羊肉串,2鸡翅,啤酒两瓶。
鸡翅没得啦,点别的吧,肉精吧。辣一点。

两者的比较啊:
路边的生意不稳定,往往就是那几个时间,客源不固定的,人多混乱,所以生意也是不稳定的。烤肉的时候谁都想最先吃到啊,烤肉老板一个人,所以忙的混乱啊。所有的人都没有事情,都盯着这里看,烤肉多那一串,考的好,大家都是比较的清楚的。
这里出现了什么关系了呢?
紧耦合
客户和肉串老板的紧耦合,所以容易出错和乱起来,也容易挑剔。这里就是行为的请求者和行为的实现者的紧耦合。我们需要记录哪几个人的羊肉串,有没有特殊的要求(辣不辣),付钱了没有,谁先谁后啊。这个都是请求做什么哦。对于请求的做出记录哦,也就是日志。
如果有人要求撤出请求不要了,或者有人要求重新烤过,这其实就是什么呢?
撤销和重做吧
所以啊,所有的请求排队或者记录日志,一节支持可以撤销的操作等行为时。行为的请求者和实现者之间的紧耦合是不是太合适的。

我们再说说烤肉店吧!
我们不认识烤肉的师傅,见都没有见到。我们只需要给接待的服务员说就好了。她给我们记录,然后将订单交给师傅去做。都有订单,必有先后顺序。不会乱,不会遗忘。
服务员,肉串太多了,给我少一串好?服务员在订单上画了一笔。搞定,然后通知师傅。让服务员解耦我们的客户与烤肉者之间的耦合这的不错哦
编程融入生活!
技术分享

我们的抽象命令

//抽象命令
    public abstract class Command
    {
        protected Barbecuer receiver;//烤肉串的执行者

        public Command(Barbecuer receiver)
        {
            this.receiver = receiver;
        }

        //执行命令
        abstract public void ExcuteCommand();
    }

这个命令的实现类,考啥子东西呢?考火腿,肌肉,还是其他的一些东西呢?

//烤羊肉串命令
    class BakeMuttonCommand : Command
    {
        public BakeMuttonCommand(Barbecuer receiver)
            : base(receiver)
        { }

        public override void ExcuteCommand()
        {
            receiver.BakeMutton();
        }
    }

    //烤鸡翅命令
    class BakeChickenWingCommand : Command
    {
        public BakeChickenWingCommand(Barbecuer receiver)
            : base(receiver)
        { }

        public override void ExcuteCommand()
        {
            receiver.BakeChickenWing();
        }
    }

我们烤肉的人在干啥呢?

 //烤肉串者
    public class Barbecuer
    {
        public void BakeMutton()
        {
            Console.WriteLine("烤羊肉串!");
        }

        public void BakeChickenWing()
        {
            Console.WriteLine("烤鸡翅!");
        }
    }

还有个重要的人物就是我们的服务员啊,这个解耦的重要的工具。服务员下订单就是让我们的烤肉啊,还是其他的一些东西执行起来,最后的时候才可以去执行的。


    //服务员
    public class Waiter
    {
        private Command command;

        //设置订单
        public void SetOrder(Command command)
        {
            this.command = command;
        }
        //通知执行
        public void Notify()
        {
            command.ExcuteCommand();
        }
    }

最后看我们怎么去执行呢?

              //开店前的准备
            Barbecuer boy = new Barbecuer();  烤肉的人
            Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 创建一个烤那个啥的,谁去烤呢?就是烤肉的
            Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
            Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
            Waiter girl = new Waiter();

            //开门营业
            girl.SetOrder(bakeMuttonCommand1);//下个订单,让我们的师傅去执行
            girl.Notify();
            girl.SetOrder(bakeMuttonCommand2);
            girl.Notify();
            girl.SetOrder(bakeChickenWingCommand1);
            girl.Notify();

这个程序肯定是还有问题的吧,真实的情况怎么可以这样的呢?每次只能点一个菜呢,通知一次。
第二嘛,我们不知道厨房的东西是否还有没得?我们应该检查一下涩,让我们的服务员
第三,我们的客户点了哪些菜我们是应该做记录的,以后好收费,还有可能客服中途取消之内的东西。

服务员,有个list的订单

    public class Waiter
    {
        private IList<Command> orders = new List<Command>();

        //设置订单
        public void SetOrder(Command command)
        {
            if (command.ToString() == "命令模式.BakeChickenWingCommand")
            {
                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();
            }
        }
    }

执行的过程和我们的刚才是一样的哦,所以不要担心的。

命令模式:Command 将我们的一个请求封装成为一个对象,从而使你可用不同的请求对客服进行参数化,对请求排队或记录日志,以及支持可以撤销的操作。
我们看看我们的图片
技术分享

Command命令设计模式中5个角色:
(1).客户角色:创建了一个具体命令对象并确定其接收者。
Barbecuer boy = new Barbecuer(); 烤肉的人
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 命令,烤肉的人是接收者

(2).命令角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个java接口或java抽象类实现。
这个就是我们上面的Command,我们的服务员依赖于他。必须有命令服务员才去通知我们的厨房哦

(3).具体命令角色:定义一个接受者和行为之间的弱耦合;实现execute方法,负责调用接收者的相应操作。execute方法通常叫做 执行方法。
这里好理解吧,我们这个方法依赖于我们的具体的执行者,烤肉的人。烤肉的人里面的哪种方法呢?我们烤的是啥子?

(4).请求者(Invoke)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
这个就是相当于我们的服务员哦,对吧!

(5).接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。

我们每一个命令的具体的执行者就是他,他就是烤肉的老板

命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。每一个命令都是一个操作,命令请求发出请求要求执行一个操作;命令接受方收到请求,并执行操作。命令模式允许命令请求方和命令接收方独立开来,使得命令请求方不必 知道命令接收方的接口,更不必知道请求是怎么被接收,以及操作是否被执行,何时被执行,以及是怎么被执行的。

服务员

//请求者角色  
class Invoker{  
        private Command command;  
        public Invoker(Command command){  
                this.command = command;  
        }  
        public void action(){  
                command.execute();  
        }  
} 

烤肉的

//接收者  
class Receiver{  
//行动方法  
        public void action(){  
                System.out.println("Action has been taken.");  
        }  
}  

服务员依赖于Command ,Command 依赖于我们的接受者,烤肉的那个人。这样就间接的传达话语!

//抽象命令角色  
interface Command{  
    void execute();  
}  
//具体命令类  
class ConcreteCommand implements Command{  
        private Receiver receiver;  
        public ConcreteCommand(Receiver receiver){  
                this.receiver = receiver;  
        }  
        public void execute(){  
                receiver.action();  
      }  
}  

客服端怎么样呢?

//客户端  
public class Client{  
         public static void main(String[] args){  
        //客户端创建命令接受者
            Receiver receiver = new Receiver();  
        //客户端创建具体命令,并指定命令接受者
             Command command = new ConcreteCommand(receiver);  
        //客户端创建请求者,并给请求者指定具体命令
             Invoker invoker = new Invoker(command);  
        //命令请求者发出命令请求
             invoker.action();         
     }   
}   

Command命令设计模式的优缺点:
优点: 解耦了命令请求者和接受者之间联系。请求者调用一个命令,接受者接受请求并执行相应的动作,因为使用Command模式解耦,请求者无需知道接受者任何接口。
缺点: 造成出现过多的具体命令类。

码农小汪-设计模式之-命令模式

标签:

原文地址:http://blog.csdn.net/u012881904/article/details/51155874

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!