Java 23种设计模式详尽分析与实例解析之三--行为型模式
Java设计模式
行为型模式
职责链模式
模式动机:职责链可以是一条直线、一个环或者一个树形结构。链上的每一个对象都是请求处理者,职责链模式可以将请求的处理组织成一条链,并使请求链传递,由链上的处理者对请求相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,将请求的发送者和请求的处理者解耦。
模式定义:使很多对象都有机会处理请求,从而避免请求的发送者和接收者之间的解耦关系。将这些对象连成一条链,并沿着这条链传递该请求,直到由一个对象处理它为止。
模式结构
模式分析:在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
请求在这条链上传递,直到链上的某一个对象处理此请求为止。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
模式应用:
1、Java中的异常处理机制。
命令模式
模式动机:命令模式可以对发送者和接收者完全解耦,与接收者之间没有直接引用关系,发送请求的对象只需要直到如何发送请求,而不必直到如何完成请求。
模式定义:将一个请求封装成一个对象,从而可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
模式结构:
模式分析:
命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分隔开。每一个命令都是一个操作,请求的一方发出请求,要求执行一个动作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求一方的接口,更不必知道请求是怎样被接收,以及操作是否被执行、何时被执行、以及是怎样被执行的。命令模式的关键在于引入了抽象命令接口,且发送者针对命令接口编程,只有实现了抽象命令接口的具体命令才能被接收者相关联。
模式应用:
1、 Java语言使用命令模式实现AWT/Swing GUI的委派事件模型。
2、 Unix平台的Shell编程,可以将多条命令封装在一个命令对象中,只需要一个简单的命令即可执行一个命令序列,这也是命令模式的应用实例。
解释器模式
迭代器模式
模式动机:一个聚合对象,例如一个列表(List)或者一个集合(Set)应该提供一种方法来让别人可以访问它的元素,而又不需要它的内部结构。针对不同的需要,可能还要以不同的方式遍历整个聚合对象,但是我们并不希望在聚合对象的抽象噌接口中充斥者各种不同遍历的操作。怎样一个聚合对象,又不需要了解聚合对象的内部结构,还能提供多种不同的遍历方式,即是迭代器的动机。
模式定义:迭代器模式提供方法来访问聚合对象,而不用这个对象的内部表示,其别名为游标。
模式结构:
模式分析:聚合是一个管理和组织数据对象的数据结构。聚合对象主要拥有两个职责:一是存储内部数据;二是遍历内部数据。存储数据是聚合对象最基本的职责。将遍历聚合对象中数据的行为提取出来,封装到一个迭代器中,通过专门的迭代器来遍历聚合对象的内部
数据,这就是迭代器模式的本质。迭代器模式是“单一职责原则”的完美体现
模式应用:JDK 1.2 引入了新的Java聚合框架Collections
中介者模式
模式动机:在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该将对象细化,使其只负责或呈现单一的职责。对于一个模块,可能由很多对象构成,而且这些对象之间可能存在相互的引用,为了减少对象之间之间复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式。
模式定义:用一个中介者对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
模式结构:
模式分析:中介者承担两方面的职责:中转作用:通过中介者提供的中转作用,各个同事对象需要显式引用同事,当需要和其他同事进行通信时,通过中介者即可。该中转作用中介者在结构上的支持。协调作用:中介者可以更进一步的对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装,该协调作用属于中介者在行为上的支持。
模式应用:
1、中介者模式在事件驱动类软件中应用比较多,在设计GUI应用程序时,组件之间可能存在较为复杂的交互关系,一个组件的改变将影响与之相关的其他组件,此时可以使用中介者模式来对组件进行协调。
2、 MVC 是Java EE 的一个基本模式,此时控制器Controller作为一种中介者,它负责控制视图对象View和模型对象Model之间的交互。如在Struts中,Action就可以作为JSP页面与业务对象之间的中介者。
3、QQ群原理。QQ群作为人与人之间的中介者,把人组织起来,负责人与人之间的交互。
备忘录模式
模式动机:为了使软件的使用更加人性化,对于误操作,我们需要提供一种类似的机制,让软件系统可以误操作前的状态,因此需要保存每一次操作时系统的状态,一旦出现误操作,可以把存储的历史状态取出即可回到之前的状态。现在大多数软件都提供撤销的功能。
模式定义:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,在将对象恢复到原先保存的状态。它是一种对象行为型模式。
模式结构:
模式分析:由于在备忘录中存储的是原发器的中间状态,因此需要防止原发器以外的其他对象访问备忘录。备忘录对象通常封装了原发器的部分或者所有的状态,而且这些状态不能其他对象访问,也就是说不能在对象之外保存原发器状态,因为暴露其内部状态将违反封装的原则,可能有损系统的可靠性和可扩展性。为了实现对备忘录对象的封装,需要备忘录的调用进行控制:对于原发器而言,它调用备忘录的所有信息,允许原发器访问返回到先前状态所需的所有数据。理想的情况是只允许生成该备忘录的那个原发器访问备忘录的内部状态。
模式应用:软件的Ctrl+Z功能以及数据库的事务回滚操作。
观察者模式
模式动机:建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,被通知的对象称为观察者,这些观察者相互关系,可以根据需要增加删除观察者,使得系统更容易扩展。
模式定义:定义间的依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者又叫发布—订阅模式。
模式结构:
模式分析:
观察者模式描述了如何建立对象与对象之间的依赖关系,如何构造满足这种需求的系统。这一模式中的关键对象是观察者和观察目标,一旦目标可以有任意数目的与之的观察者,一旦目标的状态发生改变,所有的观察者都将得到通知。作为对这个通知的相应,每个观察者都会即时更新自己的状态,以与目标状态同步。
模式应用:Servlet技术的事件处理机制以及MVC框架,观察目标为MVC中的model,而观察者就是MVC的View,而Controller充当两者之间的中介者,当模型层的数据发生改变时,试图自动改变其显式内容。
状态模式
模式动机:在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象有状态的对象,这样的对象状态是从事先定义一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,使得系统的行为也随之发生变化。
模式定义:允许对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它类。状态模式只要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
模式结构:
模式分析:状态描述了对象状态的变化以及对象如何在每一种状态下表示出不同的行为。其关键是引入了一个抽象类来专门表示对象的状态,这个类我们抽象状态类,而对象的每一种具体状态类都继承了该类,并在不同的具体状态类中实现了不同的行为,包括各种状态类之间的转换。
模式应用:
1、 状态模式在工作流或游戏等类型的软件中得以广泛使用,甚至可以用于这些系统的核心功能设计,如在政府OA办公系统中,一个批文的状态有多种:尚未办理;正在办理;正在批示;正在审核;已经完成等各种状态,而且批文状态不同时对批文的操作也有所差异。使用状态模式可以描述工作流对象(如批文)的状态转换以及不同状态下它所具有的行为。
2、 在目前主流的RPG(Role PlayGame,角色扮演游戏)中,使用状态模式可以对游戏角色进行控制,游戏角色的升级伴随着其状态的变化和行为的变化。对于游戏程序本身也可以通过状态模式进行总控,一个游戏活动包括开始、运行、结束等状态,通过对状态的控制可以控制系统的行为,决定游戏的各个方面,因此可以使用状态模式对整个游戏的架构进行设计与实现。
策略模式
模式动机:完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。在软件开发中也常常遇到这种情况,实现某个功能有多个路径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,特能够方便的增加新的解决途径。
模式定义:定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。此模式让算法的变化不会影响到使用算法的用户。
模式结构:
模式分析:在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。
模式应用:
1、 Java SE中的容器布局管理
如上图所示,在Java SE开发中,用户需要对容器对象Container中的成员对象(例如按钮,文本框等GUI控件)进行布局,在程序运行期间由客户端动态决定一个Container对象如何布局,Java语言在JDK中提供了几种不同的布局方式,封装在不同的类中,例如BorderLayout,FlowLayout、GridBagLayout和CardLayout等。上图中Container充当环境角色Context,而LayoutManager作为所有布局类的公共负累扮演了抽象策略角色,它给出所有具体布局类所需的接口,而具体策略类就是LayoutManager的子类,也就是各种具体的布局类,它们封装了不同的布局方式。任何人都可以设计并实现自己的布局类,只许只需将自己设计的布局类作为LayoutManager的子类就可以。对于客户端而言,只需要使用Container类提供的setLayout()方法就可设置任何具体布局方式,无须关心该布局的具体实现。在JDK中Container类的代码片段如下:
public class Container extends Component{
…
LayoutManager layoutMgr;
…
public void setLayout(LayoutManager mgr){
layoutMgr=mgr;
}
}
从上述代码中可以看出,Container作为环境类,它针对抽象策略类LayoutManager进行编程,用户在使用时,根据里氏代换原则,只需要在setLayout()方法中传入一个具体布局对象即可,无须关心该布局对象的具体实现。
模板方法模式
模式动机:
模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意
模式定义:
模板方法模式(Template Method Pattern):定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法是一种类行为型模式。
模式结构:
模式分析:
模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系。在模板方法模式的使用过程中,要求开发抽象类和开发具体子类的设计师之间进行协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。实现这些具体逻辑步骤的方法称为基本方法(Primitive Method),而将这些基本法方法汇总起来的方法称为模板方法(Template Method),模板方法模式的名字从此而来。
模板方法:一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
基本方法:基本方法是实现算法各个步骤的方法,是
模板方法的组成部分。
•抽象方法(Abstract Method)
•具体方法(Concrete Method)
•钩子方法(Hook Method):“挂钩”方法和空方法
模式应用:
1、模板方法模式广泛应用于框架设计(如Spring,Struts等)中,以确保父类控制处理
流程的逻辑顺序(如框架的初始化)
2、Java单元测试工具JUnit中的TestCase类的设计。
访问者模式
模式动机:对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生。
访问者模式的目的是封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式,这就是访问者模式的模式动机。
模式定义:表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。访问者模式是一种对象行为型模式。
模式结构:
模式分析:
访问者模式包含如下角色:
• Vistor: 抽象访问者• ConcreteVisitor: 具体访问者
• Element: 抽象元素• ConcreteElement: 具体元素
• ObjectStructure: 对象结构
访问者模式中对象结构存储了不同类型的元素对象,以供不同访问者访问。
访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。
相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同访问方式访问。在访问者模式中,增加新的访问者无须修改原有系统,系统具有较好的可扩展性。
模式应用:
Java 23种设计模式详尽分析与实例解析之三--行为型模式的更多相关文章
- Java 23种设计模式详尽分析与实例解析之一--创建型模式
面向对象的设计原则 常用的面向对象设计原则包括7个,这些原则并不是独立存在的,它们相互依赖.互为补充. Java设计模式 创建型模式 简单工厂模式 模式动机: 考虑一个简单的软件应用场景,一个软件系统 ...
- Java 23种设计模式详尽分析与实例解析之二--结构型模式
Java设计模式 结构型模式 适配器模式 模式动机:在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式.通常情况下,客户端可以通过目标类的接口访问它所提供的服务.又是,现有的类可以满足客 ...
- java 23种设计模式及具体例子 收藏有时间慢慢看
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代 码可靠性. 毫无疑问,设计模式 ...
- java 23 种设计模式
一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...
- (转)java 23种设计模式
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- Java 23种设计模式
转自: http://zz563143188.iteye.com/blog/1847029 ; i<count; i++){ list.add(new MailSender()); } } pu ...
- java 23种设计模式学习。
一.3大类设计模式:创建型,结构型,行为型. a.5种创建型模式:工厂方法,抽象工厂,单例,建造者,原型. b.7种结构型模式:适配器,装饰器,代理,外观,桥接,组合,享元. c.11种行为型模式:策 ...
- java 23种设计模式 深入浅出
以下内容只作为对自己对知识进行总结,如有引用他人文章会在文段末尾表明出处: Java的23种设计模式 23种设计模式总共可以分为三大类,进行不定期更新总结,将逐步展开介绍自己对设计模式的理解,多多指教 ...
- Java 23 种设计模式的分类和功能
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及安全性的解决方案. 设计模式 ...
随机推荐
- Hdu 1301 Jungle Roads (最小生成树)
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1301 很明显,这是一道“赤裸裸”的最小生成树的问题: 我这里采用了Kruskal算法,当然用Prim算法也 ...
- BZOJ 1677: [Usaco2005 Jan]Sumsets 求和
题目 1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 617 Solved: 344[Su ...
- [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素-CSDN.NET
Women Techmaker 北京站 [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素-CSDN.NET [对话CTO]当当网熊长青:兴趣是成为优秀工程师的第一因素 发表于2 ...
- POJ--1300--Door Man【推断无向图欧拉通路】
链接:http://poj.org/problem?id=1300 题意:有n个房间.每一个房间有若干个门和别的房间相连.管家从m房间開始走.要回到自己的住处(0),问是否有一条路能够走遍全部的门而且 ...
- 【LeetCode】【Python题解】Single Number & Maximum Depth of Binary Tree
今天做了三道LeetCode上的简单题目,每道题都是用c++和Python两种语言写的.由于c++版的代码网上比較多.所以就仅仅分享一下Python的代码吧,刚学完Python的基本的语法,做做Lee ...
- MCU开发之I2C通信
程序状态字PSW是8位寄存器,用于存放程序运行的状态信息,PSW中各位状态通常是在指令执行的过程中自动形成的,但也可以由用户根据需要采用传送指令加以改变.各个标志位的意义如下: PSW.7(Cy):进 ...
- sc delete 服务名
当我们在cmd里使用 sc delete 服务名 ,来删除服务的时候,报错误,SC OpenService 失败5:拒绝访问. 这似乎是因为权限不够,解决方法. 首先,我们必须先取得管理员权限,以 ...
- switch语句:适用于一个条件有多个分支的情况---分支语句
例1: 客服选择功能,然后按按键 Console.WriteLine("查花费请按1,查余额请按2,查流量请按3,办理业务请按4,宽带请按5,人工服务请按6,集团业务请按7"); ...
- ZOJ 3331 Process the Tasks 双塔Dp
用dp[i][j]表示当前安排好了前i个任务,且机器A和机器B完成当前分配到的所有任务的时间差为j(这里j可正可负,实现的时候需要加个offset)时,完成这些任务的最早时间.然后根据j的正负,分别考 ...
- 纯JAVA驱动:sqlserver版本不同,驱动与连接也有所区别
纯JAVA驱动:// 2005 版本:驱动:Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");连接:”jd ...