大话设计模式模式二十一之命令模式

在小区门口烤肉摊看到的情景,因为要吃烤肉的人太多,都希望能最快迟到肉串,烤肉老板一个人,所以有些混乱。这还不止,老板一个人,来的人一朵,他就未必记得住谁交没交过钱,要几串,需不需要放辣等等。大家都站在那里,没什么事,于是都盯着烤肉去了,哪一串多、哪一串少、哪一串烤得好、哪一串烤得焦清清楚楚,于是挑剔也就接踵而至。这就是在编程中常说的‘紧耦合’。由于客户和烤羊肉串老板的‘紧耦合’所以使得容易出错,容易混乱,也容易挑剔。

这其实就是‘行为请求者’与‘行为实现者’的紧耦合。

我们需要记录哪个人要几串羊肉串,有没有特殊要求(放辣不放辣),付没付过钱,谁先谁后,这其实都相当于对请求做记录,应该是做日志。如果有人需要退回请求,或者要求烤肉重烤,这其实就是相当于撤销和重做。

所以对请求排队或记录请求日志,以及支持可撤销的操作等行为时,‘行为请求者’与‘行为实现者’的紧耦合是不太适合的。应该怎么办呢?

我们是烤肉请求者,烤肉的师傅是烤肉的实现者,对于开门店来说,我们用得着去看着烤肉的实现过程吗?

我们不用去认识烤肉者是谁,连他的面都不用见到,我们只需要给接待我们的服务员说我们要做什么就可以了,他可以记录我们的请求,然后再由他去通知烤肉师傅做。而且,由于我们所做的请求,其实也就是我们点肉的订单,上面由很详细的我们的要求,所有的客户都有这一份订单,烤肉师傅可以按先后顺序操作,不会混乱,也不会遗忘了。收钱的时候,也不会多收或少收。

优点还不止这里,当我们将那十串羊肉串太多了,改成六串就可以了,服务员在小本子上划了一下,然后去通知烤肉是否。这其实是在做撤销行为的操作,由于有了记录,所以最终算账还是不会错的。这中利用一个服务员来解耦客户和烤肉是否的处理好处真的很多。


这就是路边烤肉的对应,如果用户多了,请求多了,就容易乱了。

门店的方法实现时,一定要增加服务员类,但是怎么做的确是有难点。不管是烤羊肉串,还是烤鸡翅,还是其他烧烤,这些都是‘烤肉串者类’的行为,也就是他的方法,具体怎么做都是由方法内部来实现,不用去管。但对应‘服务员’类来说,他其实就是根据用户的需要,发个命令,说:“有人要十个羊肉串,有人要两个鸡翅”,这些都是命令。。。

意思就是,把‘烤肉串者’类当中的方法,分别携程多个命令类,那么它们就可以被‘服务员’来请求了。

扫描二维码关注公众号,回复: 122522 查看本文章

这些命令其实差不多都是同一个样式,于是你就可以泛化出一个抽象类,让‘服务员’只管对抽象的‘命令’发号施令就可以了。具体是什么命令,即是烤什么,由客户来决定把。



一、松耦合设计





上面的程序基本都把代码实现了,但有几个问题,第一,真实的情况其实并不是用户点一个菜,服务员就通知厨房去做一个,那样部科学,应该是点完烧烤后,服务员一次通知制作;第二,如果此时鸡翅没了,不应该是客户来判断是否还有,客户哪知道有没有呀,应该是服务员或烧烤者来否决这个请求;第三,客户到底点了哪些烧烤或饮料,者是需要记录日志的,以备收费,也包括后期的统计;第四,客户完全由可能因为点的肉串太多而考虑取消一些还没有制作的肉串。


二、松耦合



三、命令模式

命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。






命令模式的作用:

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


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



猜你喜欢

转载自blog.csdn.net/nicolelili1/article/details/80164062