同的部分(字段),提取出来设计成享元,让这些⼤量相似对象引⽤这些享元。
三、⾏为型设计模式
我们知道,创建型设计模式主要解决“对象的创建”问题,结构型设计模式主要解决“类或对象的组合”问题,那⾏为型设计模式主要解决的就是“类或对象之间的交互”问题。⾏为型模式⽐较多,有 11 种,它们分别是:观察者模式、模板模式、策略模式、职责链模式、迭代器模式、状态模式、访问者模式、备忘录模式、命令模式、解释器模式、中介模式。
1. 观察者
观察者模式将观察者和被观察者代码解耦。观察者模式的应⽤场景⾮常⼴泛,⼩到代码层⾯的解耦,⼤到架构层⾯的系统解耦,再或者⼀些产品的设计思路,都有这种模式的影⼦,⽐如,邮件订阅、RSS Feeds,本质上都是观察者模式。
不同的应⽤场景和需求下,这个模式也有截然不同的实现⽅式:有同步阻塞的实现⽅式,也有异步⾮阻塞的实现⽅式;有进程内的实现⽅式,也有跨进程的实现⽅式。同步阻塞是最经典的实现⽅式,主要是为了代码解耦;异步⾮阻塞除了能实现代码解耦之外,还能提⾼代码的执⾏效率;进程间的观察者模式解耦更加彻底,⼀般是基于消息队列来实现,⽤来实现不同进程间的被观察者和观察者之间的交互。
单例模式的几种实现方式框架的作⽤有隐藏实现细节,降低开发难度,实现代码复⽤,解耦业务与⾮业务代码,让程序员聚焦业务开发。针对异步⾮阻塞观察者模式,我们也可以将它抽象成 EventBus 框架来达到这样的效果。EventBus 翻译为“事件总线”,它提供了实现观察者模式的⾻架代码。我们可以基于此框架⾮常容易地在⾃⼰的业务场景中实现观察者模式,不需要从零开始开发。
2. 模板模式
模板⽅法模式在⼀个⽅法中定义⼀个算法⾻架,并将某些步骤推迟到⼦类中实现。模板⽅法模式可以让⼦类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。这⾥的“算法”,我们可以理解为⼴义上的“业务逻辑”,并不特指数据结构和算法中的“算法”。这⾥的算法⾻架就是“模板”,包含算法⾻架的⽅法就是“模板⽅法”,这也是模板⽅法模式名字的由来。
模板模式有两⼤作⽤:复⽤和扩展。其中复⽤指的是,所有的⼦类可以复⽤⽗类中提供的模板⽅法的代码。扩展指的是,框架通过模板模式提供功能扩展点,让框架⽤户可以在不修改框架源码的情况下,基于扩展点定制化框架的功能。
除此之外,我们还讲到回调。它跟模板模式具有相同的作⽤:代码复⽤和扩展。在⼀些框架、类库、组件等的设计中经常会⽤到,⽐如JdbcTemplate 就是⽤了回调。
相对于普通的函数调⽤,回调是⼀种双向调⽤关系。A 类事先注册某个函数 F 到 B 类,A 类在调⽤ B 类的 P 函数的时候,B 类反过来调⽤ A 类注册给它的 F 函数。这⾥的 F 函数就是“回调函数”。A 调⽤ B,B 反过来⼜调⽤ A,这种调⽤机制就叫作“回调”。
回调可以细分为同步回调和异步回调。从应⽤场景上来看,同步回调看起来更像模板模式,异步回调看起来更像观察者模式。回调跟模板模式的区别,更多的是在代码实现上,⽽⾮应⽤场景上。回调基于组合关系来实现,模板模式基于继承关系来实现。回调⽐模板模式更加灵活。
3. 策略模式
策略模式定义⼀组算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独⽴于使⽤它们的客户端(这⾥的客户端代指使⽤算法的代码)。策略模式⽤来解耦策略的定义、创建、使⽤。实际上,⼀个完整的策略模式就是由这三个部分组成的。
策略类的定义⽐较简单,包含⼀个策略接⼝和⼀组实现这个接⼝的策略类。策略的创建由⼯⼚类来完成,封装策略创建的细节。策略模式包含⼀组策略可选,客户端代码选择使⽤哪个策略,有两种确定⽅法:编译时静态确定和运⾏时动态确定。其中,“运⾏时动态确定”才是策略模式最典型的应⽤场景。
在实际的项⽬开发中,策略模式也⽐较常⽤。最常见的应⽤场景是,利⽤它来避免冗长的 if-else 或 s
witch 分⽀判断。不过,它的作⽤还不⽌如此。它也可以像模板模式那样,提供框架的扩展点等等。实际上,策略模式主要的作⽤还是解耦策略的定义、创建和使⽤,控制代码的复杂度,让每个部分都不⾄于过于复杂、代码量过多。除此之外,对于复杂代码来说,策略模式还能让其满⾜开闭原则,添加新策略的时候,最⼩化、集中化代码改动,减少引⼊ bug 的风险。
4. 职责链模式
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论