文章目录
连接:https://github.com/ouyangxizhu/design_pattern.git

三、行为型模式
1. 模板方法模式
com.ouyangxizhu.design.pattern.behavioral.templatemethod
定义
定义了一个算法的骨架,子类为一个或多个方法提供实现。
适用场景
- 一次性实现实现一个算法的不变的行为,将可变的行为交给子类实现也可以通过构造器或者setter方法,开放给客户端。
- 子类的公共行为提取到公共父类(一般是抽象类,将不变的代码用final修饰)中,防止代码重复。
优点
- 提高复用性。
- 提高扩展性
- 符合开闭原则。
缺点
- 类数目增加
- 增加系统实现复杂度
- 如果父类添加新的抽象方法,所有子类都要实现抽象方法。
源码
java.util.AbstractList#get
javax.servlet.http.HttpServlet#doPost以及其他的do…方法。
org.apache.ibatis.executor.BaseExecutor#doUpdate
模板方法和工厂方法
工厂方法是模板方法的特殊实现
模板方法和策略模式
策略模式是使不同的算法可以相互替换,可以改变算法流程,(主要针对if else)并且不影响应用层客户端的使用。
模板方法,不改变算法流程,相同实现在父类,不同的实现由子类来做。
2. 迭代器模式
com.ouyangxizhu.design.pattern.behavioral.iterator
定义
提供了一个方法可以顺序访问一个集合中的各个元素,而又不暴露该对象的内部表示。就是遍历
适用场景
- 访问一个集合中的各个元素,而又不暴露该对象的内部表示
- 给遍历不同集合的元素提供了统一的接口
优点
- 分离了集合对象内部的遍历行为
缺点
- 类的个数成对增加。
- 增加系统复杂性。
源码
java.util.Iterator
3. 策略模式
com.ouyangxizhu.design.pattern.behavioral.strategy
定义
定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化不会影响使用算法的用户。大范围的处理if,elseif。
适用场景
- 系统有很多类,区别仅在于行为不同。
- 一个系统需要动态的在几种算法中选择一种。
优点
- 符合开闭原则。
- 可以避免使用多重条件转义语句。(分成多个类)
- 提高算法的保密性和安全性。
缺点
- 客户端必须知道所有的策略类,自己决定使用哪个策略类。
- 产生很多的策略实现类。
源码
java.lang.Comparable
org.springframework.core.io.Resource
策略模式和工厂模式
工厂是创建模式,客户端给定指令,工厂创建。策略模式传入的是已经创建的对象。两个可以结合起来使用。即由工厂来创建对象。
4. 解释器模式
定义
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。为了一是一种语言,二位语言创建的解释器
适用场景
- 某个特定类型发生频率足够高时。
优点
- 语法由很多类表示,容易改变及扩展此“语言”。
缺点
- 当语法规则数目太多时,增加系统复杂度。
源码
java.util.regex.Pattern
org.springframework.expression.spel.standard.SpelExpressionParser
5. 观察者模式
定义
定义了对象之间的一对多的依赖,让多个观察者对象同时监听某一个对象主题,当主题对象发生变化时,他的所有依赖(观察者都会受到通知并更新)(被观察者对象有观察者的集合,发生特定行为时,遍历集合调用观察者的update方法(即实现Observer接口的实现方法))
适用场景
- 关联行为场景,建立一套触发的机制。
优点
- 观察者和被观察者之间建立了一套抽象的耦合,容易扩展。
- 观察者模式支持广播通信。
缺点
- 观察者之间有过多的细节依赖,提高时间消耗和程序复杂度。
- 使用要得当,要避免循环调用。
源码
java.util.Observable
java.util.Observer
java.util.EventListener
org.redisson.client.SubscribeListener
发布订阅,listener、等。
6. 备忘录模式
定义
保存一个对象的某个状态,以便在适当的时候恢复。
通过栈(或者双端队列以便可以删除最早的和取最晚的)保存相应时间的快照(这个快照也可以是和要保存对象具有相同属性的类,但是该类只有get方法,没有set方法)
适用场景
- 保存及恢复数据相关业务场景。
- 后悔的时候及想恢复到之前的状态。
优点
- 为用户提供一种可恢复机制。
- 存档信息的封装。
缺点
- 资源占用。
源码
比如文档或者网站博客的暂存(可以在内存也可以序列化)
备忘录模式和状态模式
备忘录用实例保存状态,状态模式用类保存。
7. 命令模式
定义
将请求封装成对象,以便使用不同的请求。解决了应用程序中对象的职责以及它们之间的通讯方式。
适用场景
- 请求调用者和请求接收者需要解耦,使得调用者和接收者不直接交互。
优点
- 降低耦合
- 容易扩展新命令或者一组命令。
缺点
- 命令的无限扩展会增加类的数量,会增加系统的复杂度
源码
java.lang.Runnable
命令模式和备忘录模式
可以一起使用,比如cmd的↑键,可以调出上一条命令。
8. 中介者模式
定义
定义了一个 封装一组对象如何交互的对象。通过使对象明确的相互引用来促进松散耦合。并允许独立的改变他们的交互。
适用场景
- 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。
- 交互的公共行为,如果需要改变行为,则可以添加新的中介者类。
优点
- 将一对多变为一对一,降低程序复杂度比如只和聊天室交互,不用和聊天室的所有人交互
- 类之间的解耦。(中介者可以用静态方法,也可以在中介者中过滤消息)
缺点
- 中介者过多会导致系统复杂。
源码
聊天室,群,
java.util.Timer#schedule(java.util.TimerTask, long)
中介者和观察者
可以结合使用,通知聊天室的其他人可以用观察者。
9. 责任链模式
定义
为请求创建一个接收此次请求对象的链。(里面有next属性,类型为自己的父类)
适用场景
- 一个请求需要多个对象中的一个和几个处理
优点
- 请求的发送者和接收者(处理者)解耦
- 责任链可以动态组合(客户端指定顺序)
缺点
- 如果责任链太长或者处理时间过长,会影响性能。
- 责任链可能过多。
源码
javax.servlet.FilterChain
SpringSecurity
10. 访问者模式
定义
封装作用于某数据结构(如List、Map、Set)中各元素的操作。可以在不改变个元素类的前提下,定义作用于这些元素的操作。不同的访问者,对相同的数据产生不同的行为。相同的访问者可以对不同的数据产生不同的行为(传入访问者,并调用访问者的固定方法,传入的参数是被访问者本身)
适用场景
- 当一个数据结构,包含很多类型,
- 数据与数据处理分离
优点
- 增加新的操作很容易,只需要增加新的访问者。
缺点
- 增加新的数据结构很复杂。
- 具体元素变更会比较困难
源码
java.nio.file.FileVisitor
org.springframework.beans.factory.config.BeanDefinitionVisitor
访问者和迭代器
访问者模式是对其中元素进行处理,迭代器是进行遍历。
11. 状态模式
定义
允许一个对象在其内部状态(不同的状态的类表示)改变时,改变他的行为。(状态类和上下文对象都有对方的属性,因此在上下文设置状态时,要调用自己的状态的set方法,其中的参数为上下文自己)
适用场景
- 一个对象存在不同状态,状态之间可以转换(不同的状态有不同的行为(不同的可操作方式))
优点
- 将不同的状态隔离
- 将各种状态的转换逻辑分不到State的子类当中,减少相互之间的依赖。
- 增加新的状态非常简单。
缺点
- 状态比较多时,类的数量变多,系统复杂。(当太多的时候可以分治,大的变小,小的变为更小)
源码
订单扭转的状态机。