2020-04-04 Data from O’reilly

设计模式入门

把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们。

鸭子模拟游戏案例

这是一款鸭子模拟游戏,游戏中会出现各种鸭子,鸭子会戏水,会游泳,会呱呱的叫。
现在的设计状态是设计多种鸭子的类型,比如绿头鸭,红头鸭,但是这些鸭子都会飞,都会游泳,会叫,所以只用设计一套方法,让所有的鸭子都继承这个方法集就好了。现在看来,没什么问题。

但是,随着需求的增加,公司决定新增一项功能,让鸭子会飞!

那么程序员决定在方法集合中增加一项方法,就是让鸭子会飞!但是因为这个方法集会继承给所有的鸭子,而这些多种类型的鸭子中包括木头鸭子和充气鸭子,问题来了:充气鸭子怎么会飞呢?

程序员的解决方法不对!所以他重新想了一个方法,继承可能不是很好的解决方法,那么用接口如何呢?

所以他决定给每一个方法都封装起来,飞是一个功能,叫也是一个功能,游泳也是…对于每个鸭子来说,只需要调用方法就可以啦!
屏幕快照 2020-04-04 11.15.16.png

但是这个方案立马得到了主管的否决,这完全是一个超笨的主意!这样重复的代码就会变得很多!我们需要不停的对鸭子做修改,现在是4种鸭子,那么如果是400种呢??

那么现在怎么办呢?答案是:改变!

把问题归零……
现在我们知道继承和接口都不能很好的适应这种改变,那么我们就需要一个设计原则,找出应用中可能需要变化的地方,把他们独立出来,不要把这些会变得和不变的混淆在一起。换句话说,
把会变得部分取出并且封装起来,以便以后可以轻易地改动或扩充此部分。
现在我们已经做到了将鸭子和飞和呱呱叫这两种类分离开来,那么我们改如何设计鸭子的行为呢?我们需要把鸭子的行为设计一个接口,这就是第二个设计原则:
针对接口编程,而不是针对实现编程。**所以这次我们制造一组专门来实现鸭子飞行和鸭子呱呱叫的类,我们就称之为行为类。

但是管理层对程序员提出了更高的要求!“我不明白你为什么非要把飞行这个行为设计成接口,为什么不直接抽象出来,这样不就可以使用多态了吗”也就是说,我们将这两种行为抽象成animal的makesound,这是一个接口,然后我们具体实现可以是dog的makesound(){bark();}bark(){}; 也可以是cat的makesound(){meow();}meow(){};屏幕快照 2020-04-04 11.28.49.png
第三个设计原则:多用组合,少用继承。
如你所见,使用组合简历系统具有很大的弹性,不仅可将算法(方法)封装成类,更可以“在运行时动态地改变行为”,只要组合的行为对象符合正确的接口标准即可。

以上的设计模式就是我们所学的第一个设计模式,也就是策略模式。

共享模式

“行话”

星巴克点单案例

这是在星巴克的制品间,大家都在忙碌的点单制作饮品,有位顾客点了大杯大的拿铁,常温,不加糖,星巴克的点单员立刻选择了大杯,用马克笔在杯身上写上记号,L/N/0 这是我们看不懂的东西,但是在星巴克内部这就是他们的“共享词汇”,这样制作饮品的人员就可以快速知道需要制作什么类型的饮料,也知道一些顾客要求,这大大提高了效率。同时,新来的饮品制作实习生也可以通过手册的学习,快速知道这些共享词汇。

  • 共享的模式词汇“威力巨大”

当你使用模式名称和其他开发人员或者开发团队沟通时,你们之间的交流不只是模式名称,而是一整套模式背后所象征的质量,特性,约束。

  • 模式能够让你用更少的词汇做更充分的沟通

能够快速让其他开发人员知道你对设计的想法

  • 将说话的方式保持在模式层次,可让你呆在“设计圈子”久一点

使用模式谈论软件系统,可以让你保持在设计层次

  • 共享词汇可帮你的开发团队快速充电

对于设计模式有深入了解的团队,彼此之间对于设计的看法不容易产生误解

  • 共享词汇能帮助触及开发人员迅速成长

初级开发人员向有经验的开发人员看齐

观察者模式

关注/取消关注案例

现在有一个对象,比如说是哔哩哔哩上的up主 : A, 现在我们决定要关注这个A,然后接受她的一切消息和更新,那我们就加入观察者群体,成为了观察者,过了几天我们对up主失去了兴趣,不想接受她的信息了,那么我们就取消关注,所以我们就不再是观察群体中的一员了,up主A无论有什么更新,都不会再告诉我们了。
屏幕快照 2020-04-04 12.22.53.png

⬆️这里有一个项目,我们的工作就是建立一个应用,利用wearherData对象取得数据,并且更新三个布告板:目前状况,气象统计和天气预报。
屏幕快照 2020-04-04 14.00.02.png
这是根据现有的一些需求提出的最简单的解决方案,就是获取这些数据,然后实时更新这些数据。
那么这样写有什么问题呢?
这就代表我们后续如果要在这些功能上产生变动,就必须深入到修改内部代码,修改时一个小小的变动就会导致整个功能瘫痪。而且我们的布告板的数值会产生改变,但是我们也并没有将它封装起来。

所以我们现在就来拥运用观察者模式,来解决这个项目的问题。
我们先来引入一个“话术”—-松耦合
当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。
而观察者模式就提供了一种对象设计,让主题和观察者之间松耦合。

让我们更进一步,现在我们能够实现一个update的接口,观察者可以接受到所有主题发来的更新消息,但是观察者提出了问题,为什么是由你主动传输数据过来,而不是我们主动去问你要数据呢?
**
基于这样的状况,我们引入拉和推这个概念,推是主题向观察者推送的一种方式,而拉是指观察者向主题拉取状态和数据的方式。

至此,我们就可以重做气象站啦!


感谢您的阅读
翻译和整理 by 嘉艺
2020.04.04
如有任何疑问或机会请发送邮件至email:
lucida997@outlook.com