Java 中 23 种设计模式详解:详细分析 11 种行为型模式
行为型模式
11 种行为模式的关系:
第一类: 通过父类与子类的关系进行实现
第二类: 通过两个类之间的关系进行实现
第三类: 通过类的状态进行实现
第四类: 通过中间类进行实现
策略模式(Strategy)
策略模式:
定义了一系列算法,并将每个算法封装起来,可以相互替换,算法的变化不会影响到使用算法的用户
设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口
设计一个抽象类(选用,作为辅助类),提供辅助函数
ICalculator 接口提供统一的方法
AbstractCalculator 是抽象辅助类,提供辅助方法
策略模式的决定权在于用户:
系统本身提供不同算法的实现
新增或删除算法
对各种算法做封装
策略模式多用在算法决策系统中,外部用户只需要决定使用哪一个算法即可
模板方法模式(Template Method)
模板方法模式:
一个抽象类中,定义一个主方法
再定义无数个方法,可以是抽象的,也可以是实际的方法
定义一个子类,继承抽象类,重写抽象类中的方法
通过调用抽象类,实现对子类的调用
AbstractCalculator 类中定义一个主方法 calculate()
calculate() 调用 split() 等
Plus 和 Minus 分别继承 AbstractCalculator 类
通过对 AbstractCalculator 的调用实现对子类的调用
Test 的执行过程:
首先将 exp 和"\ \ +"做参数,调用 AbstractCalculator 类里的**calculate(String,String)**方法
在 calculate(String,String) 里调用同类的 split()
然后再调用 calculate(int,int) 方法
从这个方法进入到子类中
执行完 return num1+num2 之后,将值返回到 AbstractCalculator 类,赋值给 result, 打印出来
观察者模式(Observer)
观察者模式是类与类之间的关系,不涉及继承
观察者模式类似邮件订阅和 RSS 订阅:
当你订阅了该内容,如果后续有更新,会及时接收到通知
观察者模式: 当一个对象变化时,依赖该对象的对象都会接收到通知,并且随着变化.对象之间是一对多的关系
MySubject 类是主对象
Observer1 和 Observer2 是依赖于 MySubject 的对象
当 MySubject 变化时 ,Observer1 和 Observer2 必然变化
AbstractSubject 类中定义者需要监控的对象列表,可以对这些对象进行修改:增加或者删除被监控对象
当 MySubject 变化时 ,AbstractSubject 类负责通知在列表内存在的对象
观察者模式根据关系图,新建项目,使用代码按照总体思路走一遍,这样容易理解观察者模式的思想
迭代子模式(Iterator)
迭代子模式是类与类之间的关系,不涉及继承
迭代子模式: 顺序访问聚集中的对象. 包含两层意思:
聚集对象: 需要遍历的对象
迭代器对象: 用于对聚集对象进行遍历访问
MyCollection 中定义了集合的一些操作
MyIterator 中定义了一系列迭代操作,并且持有 Collection 实例
JDK 中各个类都是这些基本的集合,加上一些设计模式,再加一些优化组合到一起的,只要掌握这些,可以写出自定义的集合类,甚至框架
责任链模式(Chain of Responsibility)
类与类之间的关系,不涉及继承
责任链模式:
有多个对象,每个对象持有对下一个对象的引用,这样形成一条链,直到某个对象决定处理该请求
请求发出者并不清楚到底最终哪个对象会处理该请求
责任链模式可以实现 :在隐瞒客户端的情况下,对系统进行动态调整
Abstracthandler 类提供了 get 和 set 方法,方便 MyHandler 类设置和修改引用对象
MyHandler 类是核心,实例化后生成一系列相互持有的对象,构成一条链
链接上的请求可以是一条链,可以是一个树,还可以是一个环
模式本身不受这个约束,需要自定义实现
在同一个时刻,命令只允许由一个对象传给另一个对象,不允许传给多个对象
命令模式(Command)
类与类之间的关系,不涉及继承
命令模式理解示例:
司令员的作用是: 发出口令
口令经过传递,传到士兵耳中,士兵去执行
这个过程好在:司令,口令,士兵三者相互解藕
任何一方都不用去依赖其它方,只需要做好自身的事即可
司令员要的是结果,不会去关注士兵到底怎么实现的
Invoker 是调用者(司令员)
Receiver 是被调用者(士兵)
MyCommand 是命令,实现了 Command 接口,持有接收对象
命令模式的目的: 达到命令的发出者和执行者之间的解耦,实现请求和执行分开
Struts 其实就是一种将请求和呈现分离的技术,使用了命令模式的设计思想
备忘录模式(Memento)
备忘录模式 :主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象
备忘录模式理解:
假设有原始类 A,A 中有各种属性,A 可以决定需要备份的属性
备忘录类 B 用来存储 A 的一些内部状态
类 C 用来存储备忘录,并且只能存储,不能进行修改等操作
Original 类是原始类,里面有需要保存的属性 value 及创建一个备忘录类,用来保存 value 值
Memento 类是备忘录类
Storage 类是存储备忘录的类,持有 Memento 类的实例
新建原始类时 ,value 被初始化为 egg, 后经过修改,将 value 值修改为 bulk, 最后进行恢复状态,结果成功恢复
状态模式(State)
状态模式 :当对象的状态改变时,同时改变对象的行为
状态模式理解示例:
QQ 有几种不同的状态:在线,隐身,忙碌等
每个状态对应不同的操作,而且好友也能看到相关的状态
状态模式包括两层含义:
可以通过改变状态来获得不同的行为
对象状态的变化可以被发现
State 类是个状态类
Context 类可以实现切换
状态模式的应用场景十分广泛:在做网站的时候,希望根据对象的属性,区别一些功能等,比如说权限控制等等
访问者模式(Visitor)
访问者模式将数据结构和作用于结构上的操作解耦,使得操作集合可以相对自由地进行演化
访问者模式适用于数据结构相对稳定,算法容易变化的系统:
访问者模式使得算法操作增加变得更加容易
若系统数据结构对象易于变化,经常有新的对象增加进来,则不适合使用访问者模式
访问者模式的特点:
优点: 增加操作容易
增加操作意味着增加新的访问者
访问者模式将有关行为集中到一个访问者对象中, 这些行为的改变不影响系统数据结构
缺点: 增加新的数据结构很困难
访问者模式 :是一种分离对象数据结构和行为的方法,通过这种分离,可以达到为一个被访问者动态添加新的操作而无需做任何修改的效果
一个 Visitor 类,存放要访问的对象
Subject 类中有 accept 方法,接收将要访问的对象 ,getSubject() 获取将要被访问的属性
访客模式适用场景:
如果要为一个现有的类增加新功能:
新功能是否会与现有功能出现兼容性问题
以后会不会还有新功能需要添加
如果类不允许修改代码怎么处理
这些问题最好的解决办法就是访客模式
访问者模式适用于数据结构相对稳定的系统,将数据结构和算法解耦
中介者模式(Mediator)
中介者模式是用来降低类与类之间的耦合的:
类与类之间有依赖关系的话,不利于功能的拓展和维护
因为只要修改一个对象,其它关联的对象都要进行修改
中介者模式: 只需要关心 Mediator 类的关系,具体类与类之间的关系及调度交给 Mediator, 与 Spring 容器的作用类似
User 类统一接口
User1 和 User2 分别是不同的对象:
二者之间有关联
如果不采用中介者模式.则需要二者相互持有引用,这样二者的耦合度很高
为了解耦,引入了 Mediator 类,提供统一接口
MyMediator 为实现类:
持有 User1 和 User2 的实例,用来实现对 User1 和 User2 的控制
这样 User1 和 User2 两个对象就可以相互独立,只需保持与 Mediator 之间的关系就可以
Mediator 类用来维护
解释器模式(Interpreter)
解释器模式一般主要应用在 OOP 开发中的编译器开发中,适用面比较窄
Context 类是一个上下文环境类
Plus 和 Minus 分别是计算的实现
解释器模式是来用作各种各样的解释器 z
版权声明: 本文为 InfoQ 作者【攻城狮Chova】的原创文章。
原文链接:【http://xie.infoq.cn/article/8788422e6dc4b00e0a6a507a6】。文章转载请联系作者。
评论