命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但是行为实现者更改的时候,请求者也得随之更改。
那么如何将"行为请求者"与"行为实现者"解耦?
命令模式就将接收者抽象成了一组命令对象来实现请求者与接受者之间的解耦,也就是:调用者→命令→接受者。
可以想象Linux中的命令、Windows中CMD的命令等等,我们只要发出命令即可,不需要知道哪个接收者去实行的。这里我们是调用者,命令,后台命令对应的Shell脚本就是接收者。
在日常项目管理中,架构把工作分成了设计、开会评审、开发、团建、干不完加班等等,架构直接找开发的时候会很累听,所以提升出一个组长,让组长去给开发布置各种任务命令,架构不需要管发出的命令是哪个开发实现的。
一、代码实现项目管理
1.先把开发者(命令具体实现者)建立出来,支持啥命令就提供能干了啥的实行者。
packagecom.xing.design.command.coder; /*** 阿宾* @author xing*/publicclassABin { /*** 会找妹子*/publicvoidfindGirl() { System.out.println("阿宾找来了妹子"); } /*** 组织团建*/publicvoidtogetherHi() { System.out.println("阿宾组织团建"); } publicvoidwork() { System.out.println("阿宾在加班"); } } packagecom.xing.design.command.coder; publicclassLi { /*** 会开发*/publicvoidcoding() { System.out.println("小李完成了开发任务"); } /*** 会吹牛逼*/publicvoidchuiNB() { System.out.println("小李吹了个牛逼"); } publicvoidwork() { System.out.println("小李在加班"); } } packagecom.xing.design.command.coder; /*** 小齐* @author xing*/publicclassQi { /*** 会画图*/publicvoiddraw() { System.out.println("小齐画完图了。"); } publicvoidwork() { System.out.println("小齐在加班"); } } packagecom.xing.design.command.coder; /*** 小王* @author xing*/publicclassWang { privateintnum=0; /*** 会开发*/publicvoidcoding() { this.num++; System.out.println("小王完成了开发任务"); if(this.num>1) { neiJuan(); } } publicvoidwork() { System.out.println("小王在加班"); } /*** 会内卷*/publicvoidneiJuan() { System.out.println("可以啊,小王开始内卷了啊"); } } packagecom.xing.design.command.coder; /*** 小张 */publicclassZhang { /*** 会吹牛逼*/publicvoidchuiNB() { System.out.println("小张划水摸鱼并吹了一天牛逼"); } publicvoidwork() { System.out.println("小张在加班"); } }
2.抽象出一个命令接口,里面有一个执行方法
packagecom.xing.design.command; /*** 命令接口* @author xing*/publicinterfaceCommand { /*** 执行命令*/voidexecute(); }
3.将上述命令全部实现
packagecom.xing.design.command.impl; importcom.xing.design.command.Command; importcom.xing.design.command.coder.Li; importcom.xing.design.command.coder.Zhang; /*** 吹牛逼命令* @author xing*/publicclassChuiNBCommandimplementsCommand{ privateZhangzhang; privateLili; publicChuiNBCommand() {} publicChuiNBCommand(Zhangzhang,Lili) { this.zhang=zhang; this.li=li; } publicvoidexecute() { // 产生一个1-2之间的随机数 1.5以上交给zhang吹牛逼 doublerandom=Math.random()*(2-1)+1; System.out.println(random); if(random>1.5) { zhang.chuiNB(); }else { li.chuiNB(); } } } packagecom.xing.design.command.impl; importcom.xing.design.command.Command; importcom.xing.design.command.coder.Li; importcom.xing.design.command.coder.Wang; /*** 开发命令* @author xing* @createTime*/publicclassCodingCommandimplementsCommand{ privateLili; privateWangwang; publicCodingCommand(Lili,Wangwang) { this.li=li; this.wang=wang; } publicvoidexecute() { li.coding(); wang.coding(); } } packagecom.xing.design.command.impl; importcom.xing.design.command.Command; importcom.xing.design.command.coder.Qi; /*** 画图命令* @author xing* @createTime*/publicclassDrawCommandimplementsCommand{ privateQiqi; publicDrawCommand(Qiqi) { this.qi=qi; } publicvoidexecute() { qi.draw(); } } packagecom.xing.design.command.impl; importcom.xing.design.command.Command; importcom.xing.design.command.coder.ABin; importcom.xing.design.command.coder.Li; importcom.xing.design.command.coder.Qi; importcom.xing.design.command.coder.Wang; importcom.xing.design.command.coder.Zhang; /*** 加班卖命* @author xing*/publicclassGoDieCommandimplementsCommand{ privateABinaBin; privateLili; privateQiqi; privateWangwang; privateZhangzhang; publicGoDieCommand(ABinaBin, Lili, Qiqi, Wangwang, Zhangzhang) { this.aBin=aBin; this.li=li; this.wang=wang; this.qi=qi; this.zhang=zhang; } publicvoidexecute() { aBin.work(); li.work(); qi.work(); wang.work(); zhang.work(); System.out.println("怕猝死的跑了,内卷的还在干活。。。吹牛逼的加班也猝死不了。。。"); } } packagecom.xing.design.command.impl; importcom.xing.design.command.Command; importcom.xing.design.command.coder.ABin; /*** 团建命令,按摩唱歌嗨起来* @author xing* @createTime*/publicclassHiCommandimplementsCommand{ privateABinaBin; publicHiCommand(ABinaBin) { this.aBin=aBin; } publicvoidexecute() { aBin.togetherHi(); } } packagecom.xing.design.command.impl; importcom.xing.design.command.Command; importcom.xing.design.command.coder.ABin; /*** 上妹子* @author xing*/publicclassUpGirlCommandimplementsCommand{ privateABinaBin; publicUpGirlCommand(ABinaBin) { this.aBin=aBin; } publicvoidexecute() { aBin.findGirl(); } }
3.整一个命令管理器,用来方便架构调用
packagecom.xing.design.command; importcom.xing.design.command.coder.ABin; importcom.xing.design.command.coder.Li; importcom.xing.design.command.coder.Qi; importcom.xing.design.command.coder.Wang; importcom.xing.design.command.coder.Zhang; importcom.xing.design.command.impl.ChuiNBCommand; importcom.xing.design.command.impl.CodingCommand; importcom.xing.design.command.impl.DrawCommand; importcom.xing.design.command.impl.GoDieCommand; importcom.xing.design.command.impl.HiCommand; importcom.xing.design.command.impl.UpGirlCommand; /*** 命令管理器* @author xing*/publicclassCommandManager { publicstaticvoidexecute(Stringcommand) { switch (command) { case"开会": //初始化命令newChuiNBCommand(newZhang(),newLi()).execute(); break; case"开发": newCodingCommand(newLi(),newWang()).execute(); break; case"设计": newDrawCommand(newQi()).execute(); break; case"加班": newGoDieCommand(newABin(), newLi(), newQi(), newWang(), newZhang()).execute(); break; case"团建": newHiCommand(newABin()).execute(); break; case"花姑娘": newUpGirlCommand(newABin()).execute(); break; default: System.out.println("不支持命名->"+command); break; } } }
4.编写main方法测试
packagecom.xing.design.command; publicclassCommandDemo { publicstaticvoidmain(String[] args) { // 架构发命令啦System.out.println("----------------发出开发命令开始----------------"); CommandManager.execute("开发"); System.out.println("----------------开发命令处理结束----------------"); System.out.println("----------------发出开会评审命令开始----------------"); CommandManager.execute("开会"); System.out.println("----------------开会命令处理结束----------------"); System.out.println("----------------发出设计画图命令开始----------------"); CommandManager.execute("设计"); System.out.println("----------------设计命令处理结束----------------"); System.out.println("----------------发出组织团建命令开始----------------"); CommandManager.execute("团建"); System.out.println("----------------团建命令处理结束----------------"); System.out.println("----------------发出花姑娘命令开始----------------"); CommandManager.execute("花姑娘"); System.out.println("----------------花姑娘命令处理结束----------------"); System.out.println("----------------发出加班命令开始----------------"); CommandManager.execute("加班"); System.out.println("----------------加班命令处理结束----------------"); } }
5.测试结果
架构(请求调用者)只是通过命令管理器CommandManager发出了命令,并不管组长(命令构建者)是哪个开发(命令具体实行者)实现的,组长还可以通过参数去控制具体由哪个开发实现,完美的达到了结果。
总结:
命令模式(Command Pattern)优点是降低了系统耦合度,而且可扩展性好,新的命令可以很继续实现接口添加到命令系统中去。但是也可能因为有过多的具体命令类,提升了系统复杂性。
END