行为型模式
共十一种:策略模式
、模板方法模式
、观察者模式
、命令模式
、状态模式
、责任链模式
、
迭代子模式
、备忘录模式
、访问者模式
、中介者模式
、解释器模式
下面是设计模式的UML的结构图(重要的东西记在心上
)
下面从定义
,应用实例
和模式优缺点
以及源码体现
探讨设计模式。
观察者模式
观察者定义
:定义对象之间的一种一对多的依赖的关系
,当一个对象的状态发生改变
时,所有依赖于它的对象都得到通知并自动更新
应用实例
:拍卖通知竞价者,java事件处理机制
,以及mvc模式
(model可对应于观察者模式中的观察目标,而view对应于观察者,control可充当两者之间的中介者)
优点
:
观察者和被观察者是抽象耦合的
- 建立
一套触发机制
缺点
:
- 如果一个观察目标对象有很多直接和间接观察者,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间存在循环依赖,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
java事件模型
: 目标角色(如界面组件)负责发布事件,而观察者角色(事件处理者)
可以向目标订阅它所感兴趣的事件。当一个具体目标产生一个事件时,它将通知所有订阅者。事件的发布者称为事件源(Event Source)
,而订阅者称为事件监听器(Event Listener)
,在这个过程中还可以通过事件对象(Event Object)
来传递与事件相关的信息,可以在事件监听者的实现类中实现事件处理,因此事件监听对象又可以称为事件处理对象。事件源对象
、事件监听对象(事件处理对象)
和事件对象
构成了Java事件处理模型的三要素
。
java源码的体现
:
java.util.Observer
java.awt.event.ActionListener
模板方法模式
模板方法定义
:定义了一个算法骨架
,而将一些步骤延迟到子类中
,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤
应用实例
:jdbcTemplate,工作流
优点
:
- 封装不变部分,扩展可变部分。
- 提取公共代码,便于维护。
- 行为由父类控制,子类实现。
缺点
:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
java源码的体现
:
java.util.concurrent.ThreadPoolExecutor#runWorker
java.io.InputStream#read(byte[], int, int)
命令模式
命令模式定义
:将一个请求封装为一个对象
,从而使得你可用不同的请求对客户进行参数化
,可以对请求排队或者记录请求日志,以及支持可撤销的操作
应用实例
:GUI中每一个按钮都是一条命令,处理日志
优点
:
- 降低了系统耦合度,请求者与接收者之间实现完全解耦
- 新的命令可以很容易添加到系统中去。
缺点
:使用命令模式可能会导致某些系统有过多的具体命令类
关键代码
:
- received 真正的命令执行对象
- Command 对象(对received的动作分解一个或者多个command对象)
- invoker 使用命令对象的入口
java源码的体现
:
java.lang.Runnable的接口实现(其中run方法就是要执行的命令调用过程)
状态模式
状态模式定义
:允许一个对象再其内部状态改变时改变它的行为
,让对象看起来似乎修改它的类
应用实例
:条件分支的代替者,行为 随着状态而改变
优点
:
- 封装了状态的转换规则
- 将
所有与某个状态有关的行为放到一个类
中。允许状态转换逻辑
与状态对象合成一体,而不是提供一个巨大的条件语句块
缺点
:- 状态模式的使用必然会增加系统类和对象的个数
- 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码
特点
:需要一个全局的context对象来引用当前的状态,对象的不同状态用不子类来标识,在进行状态的转变过程中,需要改变子类的转换规则
java源码的体现
:
暂时没有好的例子,后期补充
责任链模式
责任链模式定义
:使多个对象都有机会处理请求
,从而避免了请求的发送者和接收者之间的耦合
关系 ,将这些对象连成一条链
,并沿着这条链传递该请求,直到有一 个对象处理它为止
应用实例
:条件分支的代替者,行为 随着状态而改变
优点
:
- 降低耦合度。它将请求的
发送者和接收者
解耦增强给对象指派职责的灵活性
。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任
- 增加
新的请求处理类很方便
缺点
:- 不能保证请求一定被接收
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用
特点
:同命令模式比较与状态模式之间的联系与区别命令模式与责任链模式的区别
命令模式:将多个命令只提交给一个执行该命令的对象(
指定调用
)
职责链模式相反:只将一个请求提交给多个能执行该命令的(链式调用
)状态模式与责任链模式的区别
状态模式是让各个状态对象自己知道其下一个处理的对象是谁,即在编译时便设定好了的;(
内部跳转
,一个处理
)
职责链模式中的各个对象并不指定其下一个处理的对象到底是谁,只有在客户端才设定。(外部设定
,一个或多个处理
)
java源码的体现
:
javax.servlet.Filter#doFilter()
java.util.logging.Logger#log()