码农小汪-设计模式之-命令模式
2016-04-16 19:36
417 查看
大话设计模式的例子讲的非常的好,理解起来也方便!有时候忘了。想到这些特殊的例子感觉就是特别爽。
烤羊肉串带来的思考!
路边摊羊肉串:
老板,我这里排的比较先啊,我最先给钱。老板这个没有熟啊。我的是 辣的啊!老板没有放盐啊!场面混乱,已经分不清谁是谁的啊,人太多了。烤肉的质量也受到了影响,心情不好也就不好啊。烤肉的人心情受到了顾客的影响。
店面的烤肉
服务员,给我来两串羊肉串,2鸡翅,啤酒两瓶。
鸡翅没得啦,点别的吧,肉精吧。辣一点。
两者的比较啊:
路边的生意不稳定,往往就是那几个时间,客源不固定的,人多混乱,所以生意也是不稳定的。烤肉的时候谁都想最先吃到啊,烤肉老板一个人,所以忙的混乱啊。所有的人都没有事情,都盯着这里看,烤肉多那一串,考的好,大家都是比较的清楚的。
这里出现了什么关系了呢?
紧耦合
客户和肉串老板的紧耦合,所以容易出错和乱起来,也容易挑剔。这里就是行为的请求者和行为的实现者的紧耦合。我们需要记录哪几个人的羊肉串,有没有特殊的要求(辣不辣),付钱了没有,谁先谁后啊。这个都是请求做什么哦。对于请求的做出记录哦,也就是日志。
如果有人要求撤出请求不要了,或者有人要求重新烤过,这其实就是什么呢?
撤销和重做吧
所以啊,所有的请求排队或者记录日志,一节支持可以撤销的操作等行为时。行为的请求者和实现者之间的紧耦合是不是太合适的。
我们再说说烤肉店吧!
我们不认识烤肉的师傅,见都没有见到。我们只需要给接待的服务员说就好了。她给我们记录,然后将订单交给师傅去做。都有订单,必有先后顺序。不会乱,不会遗忘。
服务员,肉串太多了,给我少一串好?服务员在订单上画了一笔。搞定,然后通知师傅。让服务员解耦我们的客户与烤肉者之间的耦合这的不错哦
编程融入生活!
![](http://b.hiphotos.baidu.com/image/pic/item/242dd42a2834349be20b3717ceea15ce36d3be17.jpg)
我们的抽象命令
这个命令的实现类,考啥子东西呢?考火腿,肌肉,还是其他的一些东西呢?
我们烤肉的人在干啥呢?
还有个重要的人物就是我们的服务员啊,这个解耦的重要的工具。服务员下订单就是让我们的烤肉啊,还是其他的一些东西执行起来,最后的时候才可以去执行的。
最后看我们怎么去执行呢?
这个程序肯定是还有问题的吧,真实的情况怎么可以这样的呢?每次只能点一个菜呢,通知一次。
第二嘛,我们不知道厨房的东西是否还有没得?我们应该检查一下涩,让我们的服务员
第三,我们的客户点了哪些菜我们是应该做记录的,以后好收费,还有可能客服中途取消之内的东西。
服务员,有个list的订单
执行的过程和我们的刚才是一样的哦,所以不要担心的。
命令模式:Command 将我们的一个请求封装成为一个对象,从而使你可用不同的请求对客服进行参数化,对请求排队或记录日志,以及支持可以撤销的操作。
我们看看我们的图片
![](http://d.hiphotos.baidu.com/image/pic/item/377adab44aed2e7318f1c5be8001a18b87d6fa0c.jpg)
Command命令设计模式中5个角色:
(1).客户角色:创建了一个具体命令对象并确定其接收者。
Barbecuer boy = new Barbecuer(); 烤肉的人
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); 命令,烤肉的人是接收者
(2).命令角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色,通常由一个java接口或java抽象类实现。
这个就是我们上面的Command,我们的服务员依赖于他。必须有命令服务员才去通知我们的厨房哦
(3).具体命令角色:定义一个接受者和行为之间的弱耦合;实现execute方法,负责调用接收者的相应操作。execute方法通常叫做 执行方法。
这里好理解吧,我们这个方法依赖于我们的具体的执行者,烤肉的人。烤肉的人里面的哪种方法呢?我们烤的是啥子?
(4).请求者(Invoke)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
这个就是相当于我们的服务员哦,对吧!
(5).接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
我们每一个命令的具体的执行者就是他,他就是烤肉的老板
命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。每一个命令都是一个操作,命令请求发出请求要求执行一个操作;命令接受方收到请求,并执行操作。命令模式允许命令请求方和命令接收方独立开来,使得命令请求方不必 知道命令接收方的接口,更不必知道请求是怎么被接收,以及操作是否被执行,何时被执行,以及是怎么被执行的。
服务员
烤肉的
服务员依赖于Command ,Command 依赖于我们的接受者,烤肉的那个人。这样就间接的传达话语!
客服端怎么样呢?
Command命令设计模式的优缺点:
优点: 解耦了命令请求者和接受者之间联系。请求者调用一个命令,接受者接受请求并执行相应的动作,因为使用Command模式解耦,请求者无需知道接受者任何接口。
缺点: 造成出现过多的具体命令类。
烤羊肉串带来的思考!
路边摊羊肉串:
老板,我这里排的比较先啊,我最先给钱。老板这个没有熟啊。我的是 辣的啊!老板没有放盐啊!场面混乱,已经分不清谁是谁的啊,人太多了。烤肉的质量也受到了影响,心情不好也就不好啊。烤肉的人心情受到了顾客的影响。
店面的烤肉
服务员,给我来两串羊肉串,2鸡翅,啤酒两瓶。
鸡翅没得啦,点别的吧,肉精吧。辣一点。
两者的比较啊:
路边的生意不稳定,往往就是那几个时间,客源不固定的,人多混乱,所以生意也是不稳定的。烤肉的时候谁都想最先吃到啊,烤肉老板一个人,所以忙的混乱啊。所有的人都没有事情,都盯着这里看,烤肉多那一串,考的好,大家都是比较的清楚的。
这里出现了什么关系了呢?
紧耦合
客户和肉串老板的紧耦合,所以容易出错和乱起来,也容易挑剔。这里就是行为的请求者和行为的实现者的紧耦合。我们需要记录哪几个人的羊肉串,有没有特殊的要求(辣不辣),付钱了没有,谁先谁后啊。这个都是请求做什么哦。对于请求的做出记录哦,也就是日志。
如果有人要求撤出请求不要了,或者有人要求重新烤过,这其实就是什么呢?
撤销和重做吧
所以啊,所有的请求排队或者记录日志,一节支持可以撤销的操作等行为时。行为的请求者和实现者之间的紧耦合是不是太合适的。
我们再说说烤肉店吧!
我们不认识烤肉的师傅,见都没有见到。我们只需要给接待的服务员说就好了。她给我们记录,然后将订单交给师傅去做。都有订单,必有先后顺序。不会乱,不会遗忘。
服务员,肉串太多了,给我少一串好?服务员在订单上画了一笔。搞定,然后通知师傅。让服务员解耦我们的客户与烤肉者之间的耦合这的不错哦
编程融入生活!
![](http://b.hiphotos.baidu.com/image/pic/item/242dd42a2834349be20b3717ceea15ce36d3be17.jpg)
我们的抽象命令
//抽象命令 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 将我们的一个请求封装成为一个对象,从而使你可用不同的请求对客服进行参数化,对请求排队或记录日志,以及支持可以撤销的操作。
我们看看我们的图片
![](http://d.hiphotos.baidu.com/image/pic/item/377adab44aed2e7318f1c5be8001a18b87d6fa0c.jpg)
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模式解耦,请求者无需知道接受者任何接口。
缺点: 造成出现过多的具体命令类。