设计模式遗珠(二)

640?

昨晚被杰伦的新歌刷屏了吧,当阿信出来的时候,我有点泪崩,我的青春呀,杰伦,五月天,满满的回忆,哈哈。之前转载过一篇关于五月天的故事,《

终于终于,我们来到了设计模式学习的最后一篇,是整个干货系列的最后一篇了,还真有点舍不得,原来一个设计模式能学习这么久,也佩服自己的坚持。

期间有过学习写作课的时间,也有过偷懒的时间,好在都坚持下来了,好在我还在,你还在关注,我们一直都在努力,一直都在进步。

话不多说,先进入今天的主题,来聊聊最后的几个设计模式。

640?wx_fmt=jpeg

解释器模式

解释器模式:使用解释器模式(Interpreter Pattern)为语言创建解释器。

场景: 还记得我们之前鸭子的例子么。Duck Pond的模拟器。在这里,我们可能还想到把它拿来当做儿童学习编程的教育工具。使用这个模拟器,每个孩子都可以用一种简单的语言来控制一只鸭子。

比如我们需要使用一门语言来控制鸭子左转、右转、甚至是飞翔。那我们现在需要做的事情,就是表现并解释语法中的句子,好让学习的同学看到用这个语言控制鸭子的效果。

640?wx_fmt=jpeg

如何实现: 当你需要实现一个简单的语言时,就使用解释器模式定义语法的类,并用一个解释器解释句子。每个语法规则都用一个类代表。

这就是一个将鸭子语言转换成类的例子,特别需要注意的是,类直接映射到语法

640?wx_fmt=jpeg

要想解释这种语言,就调用每个表达式类型的interpret()方法。此方法需要传入一个上下文(Context)----也就是我们正在解析的语言字符串输入流--然后进行比对并采取适当的动作。

解释器模式的优点解释器的用途和缺点
将每一个语法规则表示成一个类,方便于实现语言当你需要实现一个简单的语言时,使用解释器
因为语法由许多类表示,所以你可以轻易地改变或扩展此语言当你有一个简单的语法,而且简单比效率更重要时,使用解释器
通过在类结构中加入新的方法,可以在解释器的同时增加新的行为,例如打印格式的美化或者进行复杂的程序验证可以处理脚本语言和编程语言

当语法规则的数目太大时,这个模式可能会变得非常繁杂。在这种情况下,使用解析器/编译器的产生器可能更合适

640?wx_fmt=jpeg

中介者模式

中介者模式:使用中介者模式(Mediator Pattern)来集中相关对象之间复杂的沟通和控制方式。

场景: 现在是物联网的时代,未来的生活,智能家居肯定占有很大的比例。比如,我们在家里,点击打盹按钮,家里的闹钟就会告诉咖啡壶开始煮咖啡。又比如,你需要制定很多方案,周末不供应咖啡、在洗澡前将喷头关闭15分钟、在丢垃圾的时候将闹钟时刻提前等。

640?wx_fmt=jpeg

但是,如果我们想要持续地追踪每个对象的每个规则,以及众多对象之间彼此错综复杂的关系,实在是不容易。

中介者给你助力: 在这个系统中,加入一个中介者,就会变得简单。

  • 每个对象都会在自己的状态改变时,告诉中介者

  • 每个对象都会对中介者所发出的请求做出作出回应

在没有中介者的情况下,所有的对象都需要认识其他对象。也就是说,对象之间是紧耦合的。有了中介者之后,对象之间彻底解耦。

中介者包含了整个系统的控制逻辑。当某个装置需要一个新的规则时,或者是一个新的装置被加入系统内,其所有需要用到的逻辑也都被加进了中介者内。

640?wx_fmt=jpeg
中介者模式的优点中介者的用途和缺点
通过将对象彼此解耦,可以增加对象的复用性中介者常常被用来协调相关的GUI组件
通过将控制逻辑集中,可以简化系统维护中介者模式的缺点是,如果设计不当,中介者对象本身会变得过于复杂
可以让对象之间所传递的消息变得简单而且大幅减少

备忘录模式

备忘录模式:当你需要让对象返回之前的状态时(例如,你的有用户请求“撤销”),就是用备忘录模式(Memento Pattern)

场景: 其实看名字,就知道备忘录是干什么的了。现在很多小伙伴都会沉迷于游戏。当你进入到更高的游戏关卡,游戏结束的几率就会提高。

对于想冲击更高成绩的你来说,肯定不希望重头开始,而且想从你结束的关卡开始。于是,就有了“储存进度”的命令,好让玩家能够存储游戏进度,避免不必要的损失,毕竟这可是自己的辛苦所得。

这个“存储进度”的功能需要设计成能够复活的角色,而进度停留在上一次的关卡。

备忘录来助力: 备忘录模式有两个重要的目标:

  • 储存系统关键对象的重要状态

  • 维护关键对象的封装

请不要忘记单一责任原则,不要把保持装填的工作和关键对象混在一起,这样比较好。这个专门掌握状态的对象,就成为备忘录。

640?wx_fmt=jpeg
备忘录模式的优点备忘录的用途和缺点
将被存储的状态放在外面,不要和关键对象混在一起,这可以帮助维护内聚备忘录用于存储状态
保持关键对象的数据封装使用备忘录的缺点:储存和恢复状态的过程可能相当耗时
提供了容易实现的恢复能力在Java系统中,其实可以考虑使用序列化(Serialization)机制储存系统的状态

640?wx_fmt=jpeg

原型模式

原型模式:当创建给定类的实例的过程很昂贵或很复杂时,就是用原型模式(Prototype Pattern)

场景: 我们还是来玩游戏。当你的英雄人物在动态创建的场景中闯荡时,遇到了庞大的敌军有待歼灭。你希望怪兽的特征能够随着场景的变化而演化。

毕竟,如果一只鸟一样的怪兽随着你的角色进入海底,实在是没有道理。最后,你还希望能够让高级用户创建他们自己的怪兽。

想法: 创建各式各样的怪兽实例,已经越来越麻烦了。将各种状态细节放在构造器中,看起来一点都不内聚。如果能够在单一区域内封装所有的实例化细节,那该多好。

原型模式来助力: 原型模式允许你通过复制现有的实例来创建新的实例(在Java中,这通常意味着使用clone()方法,或者反序列化)。这个模式的重点在于,客户的代码在不知道要实例化何种特定类的情况下,可以制造出新的实例。

640?wx_fmt=jpeg
640?wx_fmt=jpeg
原型模式的优点原型的用途和缺点
向客户隐藏制造新实例的复杂性在一个复杂的类层次中,当系统必须从其中的许多类型创建新对象时,可以考虑原型
提供让客户能够产生未知类型对象的选项使用原型模式的缺点:对象的复制有时有点复杂
在某些环境下,复制对象比创建新对象更有效
640?wx_fmt=gif
访问者模式

访问者模式:当你想要为一个对象的组合增加新的能力,且封装并不重要时,就是用访问者模式(Visitor Pattern)

场景: 现在有一家餐厅和一家煎饼屋,他们中的顾客很重视养生。在订餐之前,都会询问营养信息。因为两个商家都非常愿意迎合顾客的需求,有些顾客甚至详细得连每种原料的营养成分也不放过。

640?wx_fmt=jpeg

烦恼的地方: 看上图就知道,这简直就和潘多拉盒子一样。天知道我们接下来要加入什么新方法,而每次一有新方法加入,就必须加到两个地方。还有,万一想要加强基本系统,比如说多了食谱类,那又该怎么办呢?我们就必须改变三个地方。

访问者来助力: 访问者必须参观组合内的每个元素;这样的功能是在导游(Traverser)对象中,访问者通过导游的引导,收集组合中所有对象的状态。一旦状态被收集了,客户就可以让访问者对状态进行各种操作。当需要新的功能时,只要加强访问者即可。

640?wx_fmt=jpeg

访问者的优点访问者的用途和缺点
允许你对组合结构加入新的操作,而无需改变结构本身当采用访问者模式的时候,就会打破组合类的封装
想要加入新的操作,相对容易因为游走的功能牵涉其中,所以对组合结构的改变就更加困难
访问者所以进行的操作,其代码是集中在一起的
640?wx_fmt=gif
结语

难说再见,还是很高兴,你我一同坚持到了最后。在学习期间,也有很多朋友加入,甚至很多朋友就是因为看了我的这个系列才决定关注我的,在这里,对所有的读者道一声感谢。

感谢你们的持续关注,感谢你们的坚持,感谢你们的反馈,让我能完成对《Head First设计模式》这本书的拆解,虽然拆解的不怎样,但还是希望能对你有帮助。

我们一直在进步,希望能和你们一起坚定地走下去。加油!

推荐阅读:

「奔跑吧攻城狮」感谢大家的关注,现在后台回复「设计模式」赠你小编精心挑选设计模式书籍。小编想打造一个高质量交流群,回复「加群」即可解锁,也可直接微信(xuyue4087)私聊解锁。

640?wx_fmt=png
喜欢就在看吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小跃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值