命令模式
二嫂的烧烤摊
大家好,我是小赵,现任藏剑山庄高级铸剑师,在山庄里任职的这段时间,和老王他们几个成了好朋友,经常一起吹牛逼打飞机。
今天周末,晚上八点左右,我们商量着去老王他二嫂那蹭一顿烧烤吃,老王的二嫂在山楂街通汇桥上摆了个烧烤摊,据说生意还不错,比我们上班强多了。
“老板娘,10串牛肉10串羊肉1斤小龙虾!羊肉不要辣!”
“老板娘,1个鸡腿2个鸡翅2串羊肉5串金针菇,羊肉不要辣!”
“老板娘,3串鸡胗5串香菇2串羊肉2串鸡肉,鸡肉不要辣,羊肉微辣!”
“老板娘,10串羊肉2个鸡腿3个鸡翅,羊肉中辣,其他微辣!”
...............
场面一度火爆,露天的小桌子都坐满了客人,点餐的点餐,催餐的催餐,老王二嫂一个人又负责点餐还负责烤菜,忙的天昏地暗。
“老赵,来几段代码玩玩。” 老王边嗑瓜子边说,老王就是这样,对我一本正经写的程序不感冒,反倒喜欢即兴表演,把眼前看到的事情用代码的方式写下来很有兴趣。
我想了想说:“那就写顾客点餐吧。”
类图:
我是老板娘:
public class Boss { public void orderMutton(){ System.out.println("烤一份羊肉"); } public void orderChicken(){ System.out.println("烤一份鸡肉"); } public void orderBeef(){ System.out.println("烤一份牛肉"); } }
主函数:
public static void main(String[] args) { User zhangsan = new User(); zhangsan.orderBeef(); zhangsan.orderChicken(); zhangsan.orderMutton(); }
输出:
烤一份牛肉
烤一份鸡肉
烤一份羊肉
“好了,写完了,大家看看,有什么问题?”。
“调用一个类的方法,这能看出个毛线?” 老王碎了一口瓜子皮。
“小王!过来帮忙!” 还没等我发作,老王二嫂的声音就朝这边喊了过来,估计那边实在是忙不过来了。
这不,老王嗑着瓜子屁颠屁颠的过去帮忙了。
老王的帮忙
有了老王的帮忙,二嫂顿时轻松了许多,只管烤菜,点餐的任务就交给老王了。
只见老王跑来跑去四处招呼,时不时的朝二嫂那边大喊:
“002桌一份牛肉!”
“005桌一份鸡肉!”
“005桌一份羊肉!”
“006桌一份羊肉!”
..........
老王完全对接了顾客和二嫂,成为了业务请求者和业务实现者的中间人,而顾客只需要对老王发送命令。
我想着想着,画下了流程图:
由于每一个菜品都是一个命令,所以命令应该是抽象出来,并且所有菜品的最终命令都是由老王传达给二嫂执行,所以命令都有一个通知执行操作。
那么我们的类图就可以这么画:
类图画好后,程序也就呼之欲出了:
我就是老王,我是调用者:
public class Invoker { private Command command; //记录命令 public void setCommand(Command command){ this.command = command; } //将命令发送给二嫂执行 public void action(){ this.command.execute(); } }
命令抽象:
public abstract class Command { protected Receiver receiver = new Receiver(); public abstract void execute();//执行命令 }
羊肉:
public class CommandMutton extends Command { @Override public void execute() { super.receiver.mutton(); } }
鸡肉:
public class CommandChicken extends Command { @Override public void execute() { super.receiver.chicken(); } }
牛肉:
public class CommandBeef extends Command { @Override public void execute() { super.receiver.beef(); } }
我是老板娘,是命令的接收者:
public class Receiver { public void mutton(){ System.out.println("烤一份羊肉"); } public void chicken(){ System.out.println("烤一份鸡肉"); } public void beef(){ System.out.println("烤一份牛肉"); } }
客户端:
public static void main(String[] args) { Invoker wang = new Invoker(); Command mutton = new CommandMutton(); wang.setCommand(mutton); wang.action(); }
输出:
烤一份羊肉
最后的干杯
老王忙完后我们摆了一桌胡吃海喝。
老刘把我的程序拿出来吹嘘说牛的一逼,结果老王一看,崩了两个字:“扯淡!”。
“我说老赵,你这写的啥玩意儿?点一份菜我就要通知一下二嫂?我嗓子还不喊哑了吗?”
这一问,我就陷入了沉默。
短暂的思索后,我改了一下Invoker类:
public class Invoker { private List<Command> list = new ArrayList<>(); //记录命令 public void setCommand(Command command){ this.list.add(command); } //撤销命令 public void removeCommand(Command command){ this.list.remove(command); } //将命令发送给二嫂执行 public void action(){ for(Command command : list){ command.execute(); } } }
客户端:
public static void main(String[] args) { Invoker wang = new Invoker(); Command mutton = new CommandMutton(); Command mutton2 = new CommandChicken(); wang.setCommand(mutton); wang.setCommand(mutton2); wang.action(); }
输出:
烤一份羊肉
烤一份鸡肉
老王一看,举起酒杯一饮而尽,赞叹道:“Perfect!”
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构