设计模式遗珠(一)

通过之前一系列的学习,终于来到了我们的最后一章。剩余2个篇幅,我会把前面没有详细说明的模式,根据书本上的描述,做一个简要的说明。

这些设计模式不像之前那些那么经常地被使用。但是,他们也有相当的可取之处,如果你遇到了合适的情形,也应当毫无犹豫地采用它们。这里做了描述,就是想和大家一起通盘了解这些模式的意义。

剩余还有桥接、生成器(建造者)、责任链、享元、解释器、中介者、备忘录、原型和访问者模式。本次我们先来了解下前面4个,干货开始了。

桥接

桥接模式:使用桥接模式(Bridge Pattern)不只改变你的实现,也改变你的抽象。

场景: 现在有一个接口友好的电视遥控器,你需要使用好的OO技能,让所有的遥控器基于相同的抽象,而对此抽象又做出许多不同的实现–每部不同型号的电视都有自己的遥控器实现。

遇到难题: 你手上的遥控器会改变,而电视机也会改变。你已经将用户界面抽象出来,所以可以根据不同的电视机改变它的实现。事情还不止如此,随着使用时间的增长,用户会对此界面提出一些想法,你还必须应对他们的反馈来改变抽象。

所以你要如何建立一个OO设计,能够改变实现和抽象呢?

桥接模式来助力: 桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。

现在你就有了两个层次结构,其中一个是遥控器,而另一个是平台特定的电视机实现。有了桥接的存在,你就可以独立地改变这两个层次。

桥接的优点桥接的用途和缺点
将实现予以解耦,让它和界面之间不再永久绑定适合使用在需要跨越多个平台的图形和窗口系统上
抽象和实现可以独立扩展,不会影响到对方当需要用不同的方式改变接口和实现时,你会发现桥接模式很好用
对于“具体的抽象类”所做的改变,不会影响到客户桥接模式的缺点是增加了复杂度
生成器(建造者)模式

生成器(建造者)模式:使用生成器(Builder Pattern)封装一个产品的构造过程,并允许按步骤构造。

场景: 你家附近开了一个新主题乐园,他们邀请了一部分用户参与制定一套度假计划。客人可以选择旅馆以及各种门票、餐厅订位、甚至也可以选择登记参加特殊活动。想要制定一套度假计划,你需要建立如下这样的结构:

遇到难题: 每个客人的度假计划可能都不太一样,例如天数、活动类型等。比如说,本地游客可能就不需要旅馆,但是需要用餐甚至是特殊活动。而其他游客大老远的过去,那就需要旅馆、用餐等。

所以,这时候就需要你设计一个有弹性的数据结构,代表客人的规划,以及所有的变化;你也需要遵循一系列潜在的复杂顺序,创建这样的规则。你要如何才能提供一种方式来创建这个复杂的结构,而不会和创建它的步骤混在一起呢?

建造者模式助力: 学习过迭代器的同学还记得迭代器的方式吧。将迭代的过程封装入一个独立的对象中,并向客户隐藏集合的内部表现。在这里,我们也用相同的想法:把旅游规划的创建过程,封装到一个对象中(我们称此为生成器或建造者),然后让客户调用生成器为它创建规划。

生成器的优点生成器的用途和缺点
讲一个复杂对象的创建过程封装起来经常被用来创建组合结构
允许对象通过多个步骤来创建,并且可以改变过程与工厂模式相比,采用生成器模式创建对象的客户,需要具备更多的领域知识
向客户隐藏产品内部的表现
产品的实现可以被替换,因为客户只看到一个抽象的接口
责任链模式

责任链模式:当你想要让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式(Chain of Responsibility Pattern)

场景: 之前篇幅有个例子,是关于糖果公司卖糖果的。现在,他们收到了很多邮件,据工作人员分析,所收到的电子邮件有四类:其一,是粉丝寄来的信;其二,是父母寄来的信;其三,是商家寄来的信;其四,其他垃圾邮件。

工作人员根据职责分配,粉丝的信送到CEO手上,父母的信送到服务1部门,商家的信送到服务2部门,垃圾邮件直接删除。

改进方式: 上面所说的,还是需要负责人进行任务分配。但是,如果我们再努力一点,写一个智能过滤程序,它们会分辨这些是属于哪一类,不是挺好的。这就需要你构造一个设计,来处理这个过滤。

责任链模式助力: 通过责任链模式,你可以为某个请求创建一个对象链。每个对象依赖检查此请求,并对其进行处理,或者将它传给链中的下一个对象。

当收到电子邮件后,它会被送进第一个处理器,也就是SpamHandler,如果SpamHandler无法处理,就将它传给FanHandler,以此类推。做过Android的会不会有似曾相似的感觉,和点击事件的事件分发类似,是吧。

SpamHander -> FanHandler -> ComplaintHandler -> NewLocHandler 如果到了最后还不能处理,那你也可以选择一个万能的回收站来处理前面都不能处理的事件,这样就能完全闭合了。

责任链的优点责任链的用途和缺点
将请求的发送者和接收者解耦经常被使用在窗口系统中,处理鼠标和键盘之类的事件
可以简化你的对象,因为它不需要知道链的结构并不保证请求一定会被执行;如果没有任何对象处理它的话,它可能会落到链尾端之外(这可能也是优点)
通过改变链内的成员或调动它们的次序,允许你动态地新增或者删除责任可能不容易观察运行时的特征,有碍于除错
享元模式

享元模式:如果让某个类的一个实例能用来提供许多“虚拟实例”,就使用享元模式(Flyweight Pattern)

场景: 在热门的全球景观设计应用中,你想要加上一些树作为点缀;树有一个XY坐标位置,而且可以根据树的年龄动态地将自己绘制出来。问题是,用户可能要在他们的家庭景观设计中有非常非常多的树,看起来就像下面这样:

[外链图片转存失败(img-yqXlebO0-1569156743843)(http://wx4.sinaimg.cn/mw690/62b02411ly1g6nejismt6j20my0fgtew.jpg)]

遇到的难题: 你已经向客户努力推销了好几个月,而且他们也打算购买1000套软件,并应用到大型规划社区的景观设计。在使用一段时间后,客户发了好多抱怨:他们创建了越来越多的树,结果这个程序开始变得卡顿。

享元模式来助力: 遇到上面的问题,那我们可以重新设计系统,只要用一个树实例和一个客户对象来维护所有树的状态即可,这就是享元模式。

享元的优点享元的用途和缺点
减少运行时对象实例的个数,节省内存当一个类有许多的实例,而这些实例能被同一方法控制的时候,我们就可以使用享元模式
将许多“虚拟”对象的状态集中管理享元模式的缺点在于,一旦你实现了它,那么单个的逻辑实例将无法拥有独立而不同的行为
结语

今天的内容就和大家分享到这里了,今天分享了四个模式,我猜有几个大家平时都还用过呢。设计模式就是这样,你总会在无形之中使用上了,并且效果还不错。

这就是我们学习设计模式的目的,让我们在写代码的时候,能通过各种思维的碰撞,通过一系列的思考,通过自己平时潜移默化地进步,来使用,这样就不会有很大的负担,也能让我们能适当地运用,而不是刻意去使用。

「奔跑吧攻城狮」感谢大家的关注,现在后台回复「设计模式」赠你小编精心挑选设计模式书籍。小编最近开窍,组建了一个技术交流群,回复「加群」即可解锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员小跃

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

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

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

打赏作者

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

抵扣说明:

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

余额充值