J2EE设计模式
来源:百度文库 编辑:神马文学网 时间:2024/04/29 01:20:22
设计模式(Patterns in Java) --http://www.jdon.com
1
设计模式(Patterns in Java)
Java 提供了丰富的API,同时又有强大的数据库系统作底层支持,那么我们的编程似乎
变成了类似积木的简单"拼凑"和调用,甚至有人提倡"蓝领程序员",这些都是对现代编
程技术的不了解所至.
在真正可复用的面向对象编程中,GoF 的《设计模式》为我们提供了一套可复用的面向对
象技术,再配合Refactoring(重构方法),所以很少存在简单重复的工作,加上Java 代码
的精炼性和面向对象纯洁性(设计模式是java 的灵魂),编程工作将变成一个让你时刻体
验创造快感的激动人心的过程.
为能和大家能共同探讨"设计模式",我将自己在学习中的心得写下来,只是想帮助更多
人更容易理解GoF 的《设计模式》。由于原著都是以C++为例, 以Java 为例的设计模式
基本又都以图形应用为例,而我们更关心Java 在中间件等服务器方面的应用,因此,本站
所有实例都是非图形应用,并且顺带剖析Jive 论坛系统.同时为降低理解难度,尽量避
免使用UML 图.
如果你有一定的面向对象编程经验,你会发现其中某些设计模式你已经无意识的使用过
了;如果你是一个新手,那么从开始就培养自己良好的编程习惯(让你的的程序使用通用
的模式,便于他人理解;让你自己减少重复性的编程工作),这无疑是成为一个优秀程序
员的必备条件.
整个设计模式贯穿一个原理:面对接口编程,而不是面对实现.目标原则是:降低耦合,增
强灵活性.
1:前言
学习GoF 设计模式的重要性
建筑和软件中模式之异同
2:GoF 设计模式
A.创建模式
设计模式之Factory(工厂方法和抽象工厂)
使用工厂模式就象使用new 一样频繁.
设计模式之Prototype(原型)
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的
对象。
设计模式(Patterns in Java) --http://www.jdon.com
2
设计模式之Builder
汽车由车轮 方向盘 发动机很多部件组成,同时,将这些部件组装
成汽车也是一件复杂的工作,Builder 模式就是将这两种情况分开
进行。
设计模式之Singleton(单态)
保证一个类只有一个实例,并提供一个访问它的全局访问点
B.结构模式
设计模式之Facade
可扩展的使用JDBC 针对不同的数据库编程,Facade 提供了一种灵
活的实现.
设计模式之Proxy
以Jive 为例,剖析代理模式在用户级别授权机制上的应用
设计模式之Adapter
使用类再生的两个方式:组合(new)和继承(extends),这个已经在
"thinking in java"中提到过.
设计模式之Composite
就是将类用树形结构组合成一个单位.你向别人介绍你是某单位,
你是单位中的一个元素,别人和你做买卖,相当于和单位做买卖。
文章中还对Jive 再进行了剖析。
设计模式之Decorator
Decorator 是个油漆工,给你的东东的外表刷上美丽的颜色.
设计模式之Bridge
将"牛郎织女"分开(本应在一起,分开他们,形成两个接口),在他们之
间搭建一个桥(动态的结合)
设计模式之Flyweight
提供Java 运行性能,降低小而大量重复的类的开销.
C.行为模式
设计模式之Template
实际上向你介绍了为什么要使用Java 抽象类,该模式原理简单,使
用很普遍.
设计模式之Memento
很简单一个模式,就是在内存中保留原来数据的拷贝.
设计模式之Observer
介绍如何使用Java API 提供的现成Observer
设计模式(Patterns in Java) --http://www.jdon.com
3
设计模式之Chain of Responsibility
各司其职的类串成一串,好象击鼓传花,当然如果自己能完成,就不
要推委给下一个.
设计模式之Command
什么是将行为封装,Command 是最好的说明.
设计模式之State
状态是编程中经常碰到的实例,将状态对象化,设立状态变换器,便
可在状态中轻松切换.
设计模式之Strategy
不同算法各自封装,用户端可随意挑选需要的算法.
设计模式之Mediator
Mediator 很象十字路口的红绿灯,每个车辆只需和红绿灯交互就可
以.
设计模式之Interpreter
主要用来对语言的分析,应用机会不多.
设计模式之Visitor
访问者在进行访问时,完成一系列实质性操作,而且还可以扩展.
设计模式之Iterator
这个模式已经被整合入Java 的Collection.在大多数场合下无需自
己制造一个Iterator,只要将对象装入Collection中,直接使用Iterator
进行对象遍历。
3:英文资料
Thinking in Patterns with Java Thinking in Java 的作者Eckel 又一
著作!
CMSC491D Design Patterns In Java
Overview of Design Patterns 精确定义各个模式以及他们的关系
Design Patterns Java Companion
EJB 设计模式(英文) 从设计模式去理解EJB 或J2EE我认为是个非常有效
的办法.
设计模式(Patterns in Java) --http://www.jdon.com
4
学习GoF 设计模式的重要性
GoF 的《设计模式》也许你没有听说过,但是《Thingking in Java》(Java 编程思想)你应该
知道甚至读过吧!
在浏览《Thingking in Java》(第一版)时,你是不是觉得好象这还是一本Java 基础语言书
籍?但又不纯粹是,因为这本书的作者将面向对象的思想巧妙的融合在Java 的具体技术上,
潜移默化的让你感觉到了一种新的语言和新的思想方式的诞生。
但是读完这本书,你对书中这些蕴含的思想也许需要一种更明晰更系统更透彻的了解和掌
握,那么你就需要研读GoF 的《设计模式》了。
《Thingking in Java》(第一版中文)是这样描述设计模式的:他在由Gamma, Helm 和Johnson
Vlissides 简称Gang of Four(四人帮),缩写GoF 编著的《Design Patterns》一书中被定义
成一个“里程碑”。事实上,那本书现在已成为几乎所有OOP(面向对象程序设计)程序员都
必备的参考书。(在国外是如此)。
GoF 的《设计模式》是所有面向对象语言(C++ Java C#)的基础,只不过不同的语言将之实
现得更方便地使用。
GOF 的设计模式是一座"桥"
就Java 语言体系来说,GOF 的设计模式是Java 基础知识和J2EE 框架知识之间一座隐性的"
桥"。
会Java 的人越来越多,但是一直徘徊在语言层次的程序员不在少数,真正掌握Java 中接口
或抽象类的应用不是很多,大家经常以那些技术只适合大型项目为由,避开或忽略它们,实
际中,Java 的接口或抽象类是真正体现Java 思想的核心所在,这些你都将在GoF 的设计模
式里领略到它们变幻无穷的魔力。
GoF 的设计模式表面上好象也是一种具体的"技术",而且新的设计模式不断在出现,设计模
式自有其自己的发展轨道,而这些好象和J2EE .Net 等技术也无关!
实际上,GoF 的设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或
抽象类在实际案例中的灵活应用和智慧,让你能够真正掌握接口或抽象类的应用,从而在原
来的Java 语言基础上跃进一步,更重要的是,GoF 的设计模式反复向你强调一个宗旨:要
让你的程序尽可能的可重用。
这其实在向一个极限挑战:软件需求变幻无穷,计划没有变化快,但是我们还是要寻找出不
变的东西,并将它和变化的东西分离开来,这需要非常的智慧和经验。
而GoF 的设计模式是在这方面开始探索的一块里程碑。
设计模式(Patterns in Java) --http://www.jdon.com
5
J2EE 等属于一种框架软件,什么是框架软件?它不同于我们以前接触的Java API 等,那些
属于Toolkist(工具箱),它不再被动的被使用,被调用,而是深刻的介入到一个领域中去,
J2EE 等框架软件设计的目的是将一个领域中不变的东西先定义好,比如整体结构和一些主
要职责(如数据库操作 事务跟踪 安全等),剩余的就是变化的东西,针对这个领域中具体应
用产生的具体不同的变化需求,而这些变化东西就是J2EE 程序员所要做的。
由此可见,设计模式和J2EE 在思想和动机上是一脉相承,只不过
1.设计模式更抽象,J2EE 是具体的产品代码,我们可以接触到,而设计模式在对每个应用
时才会产生具体代码。
2.设计模式是比J2EE 等框架软件更小的体系结构,J2EE 中许多具体程序都是应用设计模式
来完成的,当你深入到J2EE 的内部代码研究时,这点尤其明显,因此,如果你不具备设计
模式的基础知识(GoF 的设计模式),你很难快速的理解J2EE。不能理解J2EE,如何能灵活应
用?
3.J2EE 只是适合企业计算应用的框架软件,但是GoF 的设计模式几乎可以用于任何应用!
因此GoF 的设计模式应该是J2EE 的重要理论基础之一。
所以说,GoF 的设计模式是Java 基础知识和J2EE 框架知识之间一座隐性的"桥"。为什么说
隐性的?
GOF 的设计模式是一座隐性的"桥"
因为很多人没有注意到这点,学完Java 基础语言就直接去学J2EE,有的甚至鸭子赶架,直
接使用起Weblogic 等具体J2EE 软件,一段时间下来,发现不过如此,挺简单好用,但是你
真正理解J2EE 了吗?你在具体案例中的应用是否也是在延伸J2EE 的思想?
如果你不能很好的延伸J2EE 的思想,那你岂非是大炮轰蚊子,认识到J2EE 不是适合所有场
合的人至少是明智的,但我们更需要将J2EE 用对地方,那么只有理解J2EE 此类框架软件的
精髓,那么你才能真正灵活应用Java 解决你的问题,甚至构架出你自己企业的框架来。(我
们不能总是使用别人设定好的框架,为什么不能有我们自己的框架?)
因此,首先你必须掌握GoF 的设计模式。虽然它是隐性,但不是可以越过的。
在著名的EJB 领域顶尖的专家Richard Monson-Haefel 的个人网站:www.EJBNow.com 中
Richard 极力推荐的几本书中就有GoF 的《设计模式》,原文如下:
Design Patterns
Most developers claim to experience an epiphany reading this book. If you‘ve never
read the Design Patterns book then you have suffered a very serious gap in your
programming education that should be remedied immediately.
翻译: 很多程序员在读完这本书,宣布自己相当于经历了一次"主显节"(纪念那稣降生和受
洗的双重节日),如果你从来没有读过这本书,你会在你的程序教育生涯里存在一个严重裂沟,
所以你应该立即挽救弥补!
设计模式(Patterns in Java) --http://www.jdon.com
6
设计模式(Patterns in Java) --http://www.jdon.com
7
建筑和软件中模式之异同
CSDN 的透明特别推崇《建筑的永恒之道》,认为从中探寻到软件的永恒之道,并就"设计模式
"写了专门文章《探寻软件的永恒之道 》,其中很多观点我看了很受启发,以前我也将"设计
模式" 看成一个简单的解决方案,没有从一种高度来看待"设计模式"在软件中地位,下面是
我自己的一些想法:
建筑和软件某些地方是可以来比喻的
特别是中国传统建筑,那是很讲模式的,这些都是传统文化使然,比如京剧 一招一式都有套
路;中国画,也有套路,树应该怎么画法?有几种画法?艺术大家通常是创造出自己的套路,比
如明末清初,水墨画法开始成熟,这时画树就不用勾勒这个模式了,而是一笔下去,浓淡几个
叶子,待毛笔的水墨要干枯时,画一下树干,这样,一个活生写意的树就画出来.
我上面这些描述其实都是一种模式,创建模式的人是大师,但是拘泥于模式的人永远是工匠.
再回到传统建筑中,中国的传统建筑是过分注重模式了,所以建筑风格发展不大,基本分南北
两派,大家有个感觉,旅游时,到南方,你发现古代名居建筑都差不多;北方由于受满人等少数
民族的影响,在建筑色彩上有些与南方迥异,但是很多细节地方都差不多.这些都是模式的体
现.
由于建筑受材料和功用以及费用的影响,所用模式种类不多,这点是和软件很大的不同.
正因为这点不同,导致建筑的管理模式和软件的管理模式就有很多不同, 有些人认识不到这
点,就产生了可以大量使用"软件蓝领"的想法,因为他羡慕建筑中"民工"的低成本.
要知道软件还有一个与建筑截然相反的责任和用途,那就是:现代社会中,计划感不上变化,
竞争激烈,所有一切变幻莫测,要应付所有这些变化,首推信息技术中的软件,只有软件能够
帮助人类去应付各种变化.而这点正好与建筑想反,建筑是不能帮助人类去应付变化的,(它
自己反而要求稳固,老老实实帮助人遮风避雨,总不能叫人类在露天或树叶下打开电脑编软
件吧).
软件要帮助人类去应付变化,这是软件的首要责任,所以,软件中模式产生的目的就和建筑不
一样了,建筑中的模式产生可以因为很多原因:建筑大师的创意;材料的革新等;建筑中这些
模式一旦产生,容易发生另外一个缺点,就是有时会阻碍建筑本身的发展,因为很多人会不思
创造,反复使用老的模式进行设计,阻碍建筑的发展.
但是在软件中,这点正好相反,软件模式的产生是因为变化的东西太多,为减轻人类的负担,
将一些不变的东西先用模式固化,这样让人类可以更加集中精力对付变化的东西,所以在软
件中大量反复使用模式(我个人认为这样的软件就叫框架软件了,比如J2EE),不但没阻碍软
件的发展,反而是推动了软件的发展.因为其他使用这套软件的人就可以将更多精力集中在
对付那些无法用模式的应用上来.
设计模式(Patterns in Java) --http://www.jdon.com
8
可以关于建筑和软件中的模式作用可以总结如下:
在软件中,模式是帮助人类向"变化"战斗,但是在软件中还需要和‘变化‘直接面对面战斗的
武器:人的思维,特别是创造 分析思维等等,这些是软件真正的灵魂,这种思维可以说只要
有实践需求(如有新项目)就要求发生,发生频度高,人类的创造或分析思维决定了软件的质
量和特点。
而在建筑中,模式可以构成建筑全部知识,当有新的需求(如有新项目),一般使用旧的模式
都可以完成,因此对人类的创造以及分析思维不是每个项目都必须的,也不是非常重要的,
对创造性的思维的需求只是属于锦上添花(除非人类以后离开地球居住了)。
设计模式(Patterns in Java) --http://www.jdon.com
9
设计模式之Factory
定义:提供创建对象的接口.
为何使用?
工厂模式是我们最常用的模式了,著名的Jive 论坛系统,就大量使用了工厂模式.
为什么说工厂模式是最常用,因为工厂模式就相当于创建对象的new. 工厂模式就是用来创
建对象的.
比如我们有一个类Sample 我们要创建Sample 的对象:
Sample sample=new Sample();
如果我们要在创建sample 之前做点事情,比如,赋值等,可以使用Sample 的构造函数:
Sample sample=new Sample(参数);
如果创建sample 时做的事情不是如赋值这样简单的事,可能是很长一段代码,如果也写入构
造函数中,那明显的就违背了面向对象的原则.封装(Encapsulation)和分派(Delegation);
我们需要将创建实例的责任与使用实例的责任分开, 使得语句
Sample sample=new Sample(参数);
就是简单的责任:使用Sample 这个实例;至于创建Sample 的任务就交给了Factory 工厂模
式.
还有,如果Sample 有个继承如MySample, 按照面向接口编程,我们需要将Sample 抽象成一
个接口.
现在Sample 是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:
Sample mysample=new MySample();
Sample hissample=new HisSample();
随着项目的深入,Sample 可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实
例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程
序中是无法避免的.
但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
你会建立一个专门生产Sample 实例的工厂:
设计模式(Patterns in Java) --http://www.jdon.com
10
public class Factory{
public static Sample creator(){
....
if (which==1)
return new MySample();
else if (which==2)
return new HisSample();
}
}
那么在你的程序中,如果要实例化MySample 时.就使用
Sample sample=Factory.creator();
这样,在整个就不涉及到Sample 的具体子类,达到封装效果,也就减少错误修改的机会,这个
原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误.这每个做过具体工作
的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,范错误可能性就越少.好象我们
从编程序中也能悟出人生道理?呵呵.
好了,言归正传,既然不可避免使用factory,那我们就认识一下工厂模式.
如何使用?
工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
上例中,我们使用的是简单的工厂方法. 这两个模式没有很明显的区别,区别在于需要创建
对象的复杂程度上。如果我们创建对象的方法变得复杂了,我们就可能要将上例中Factory
变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现:
public abstract class Factory{
public abstract Sample creator();
public abstract Sample2 creator();
}
public class SimpleFactory extends Factory{
public Sample creator(){
设计模式(Patterns in Java) --http://www.jdon.com
11
......
}
public Sample2 creator(){
......
}
}
public class BombFactory extends Factory{
public Sample creator(){
......
}
public Sample2 creator(){
......
}
}
上例中我们只有一类产品接口 Sample , 工厂方法和抽象工厂可以创建多个产品接口的实
例,比如Sample2 Sample3
FactoryMethod 往往只是创建单个的实例。Abstract Factory 创建一系列的实例组,这些实
例彼此相关。
举例1
下图是来自天极网" 阎宏"的 爪哇语言抽象工厂创立性模式介绍 中的抽象工厂图:
设计模式(Patterns in Java) --http://www.jdon.com
12
在这张图中, 有两类产品接口interface RAM 和interface CPU; 同时有两个创建方
法:MacProducer 和PCProducer,这两个创建方法中都有createCPU()和createRAM(),返回的
实例对象组是CPU 和RAM, 这是分别来自两类产品接口,表面彼此是相关的.因此它是抽象工
厂.
举例2
我们以Jive 的ForumFactory 为例:
public abstract class ForumFactory {
private static Object initLock = new Object();
private static String className =
"com.jivesoftware.forum.database.DbForumFactory";
private static ForumFactory factory = null;
public static ForumFactory getInstance(Authorization authorization) {
//If no valid authorization passed in, return null.
if (authorization == null) {
return null;
}
//以下使用了Singleton 单态模式
if (factory == null) {
synchronized(initLock) {
if (factory == null) {
设计模式(Patterns in Java) --http://www.jdon.com
13
......
try {
//动态转载类
Class c = Class.forName(className);
factory = (ForumFactory)c.newInstance();
}
catch (Exception e) {
return null;
}
}
}
}
//Now, 返回 proxy.用来限制授权对forum 的访问
return new ForumFactoryProxy(authorization, factory,
factory.getPermissions(authorization));
}
//真正创建forum 的方法由继承forumfactory 的子类去完成.
public abstract Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException;
....
}
因为现在的Jive 是通过数据库系统存放论坛帖子等内容数据,如果有人要扩展为纯粹的文
件系统存放的论坛帖子,这个工厂方法ForumFactory 就提供了提供动态接口:
private static String className =
"com.jivesoftware.forum.database.DbForumFactory";
你可以使用自己开发的创建forum 的方法代替
com.jivesoftware.forum.database.DbForumFactory 就可以.
在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Singleton 单态模式,以及
proxy 模式,proxy 模式主要用来授权用户对forum 的访问,因为访问forum有两种人:一个是
注册用户 一个是游客guest,那么那么相应的权限就不一样,而且这个权限是贯穿整个系统
的,因此建立一个proxy,类似网关的概念,可以很好的达到这个效果.
设计模式(Patterns in Java) --http://www.jdon.com
14
好了.经过上述简单描述,你对工厂模式应该有个简单的印象,如果你要钻研工厂模式,网络
上有很多英文资料,不过我觉得过分钻研也没有必要,主要是使用实践,实际使用中工厂模式
的变种很多,只要你知道这样一个大概思路,相信在实践中你会是工厂模式的设计创建高手!
设计模式(Patterns in Java) --http://www.jdon.com
15
设计模式之Prototype(原型)
定义:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.
Prototype 模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的
细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象
通过请求原型对象拷贝它们自己来实施创建。
如何使用?
因为Java 中的提供clone()方法来实现对象的克隆(具体了解clone()按这里),所以
Prototype 模式实现一下子变得很简单.
以勺子为例:
public abstract class AbstractSpoon implements Cloneable
{
String spoonName;
public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
public String getSpoonName() {return this.spoonName;}
public Object clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractSpoon is not Cloneable");
}
return object;
}
}
有两个具体实现(ConcretePrototype):
public class SoupSpoon extends AbstractSpoon
{
public SoupSpoon()
{
setSpoonName("Soup Spoon");
设计模式(Patterns in Java) --http://www.jdon.com
16
}
}
public class SaladSpoon extends AbstractSpoon
{
public SaladSpoon()
{
setSpoonName("Salad Spoon");
}
}
调用Prototype 模式很简单:
AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon = new SaladSpoon();
当然也可以结合工厂模式来创建AbstractSpoon 实例。
在Java 中Prototype 模式变成clone()方法的使用,由于Java 的纯洁的面向对象特性,使
得在Java 中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,
如Interator 遍历模式。
设计模式(Patterns in Java) --http://www.jdon.com
17
设计模式之Builder
Builder 模式定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
Builder 模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型
和内容就可以构建它们.用户不知道内部的具体构建细节.Builder 模式是非常类似抽象工
厂模式,细微的区别大概只有在反复使用中才能体会到.
为何使用?
是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机
还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配
过程也很复杂(需要很好的组装技术),Builder 模式就是为了将部件和组装过程分开.
如何使用?
首先假设一个复杂对象是由多个部件组成的,Builder 模式是把复杂对象的创建和部件的创
建分别开来,分别用Builder 类和Director 类来表示.
首先,需要一个接口,它定义如何创建复杂对象的各个部件:
public interface Builder {
//创建部件A 比如创建汽车车轮
void buildPartA();
//创建部件B 比如创建汽车方向盘
void buildPartB();
//创建部件C 比如创建汽车发动机
void buildPartC();
//返回最后组装成品结果 (返回最后装配好的汽车)
//成品的组装过程不在这里进行,而是转移到下面的Director 类中
进行.
//从而实现了解耦过程和部件
Product getResult();
}
用Director 构建最后的复杂对象,而在上面Builder 接口中封装的是如何创建一个个部件
(复杂对象是由这些部件组成的),也就是说Director 的内容是如何将部件最后组装成成品:
设计模式(Patterns in Java) --http://www.jdon.com
18
public class Director {
private Builder builder;
public Director( Builder builder ) {
this.builder = builder;
}
// 将部件partA partB partC 最后组成复杂对象
//这里是将车轮 方向盘和发动机组装成汽车的过程
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
Builder 的具体实现ConcreteBuilder:
通过具体完成接口Builder 来构建或装配产品的部件;
定义并明确它所要创建的是什么具体东西;
提供一个可以重新获取产品的接口:
public class ConcreteBuilder implements Builder {
Part partA, partB, partC;
public void buildPartA() {
//这里是具体如何构建partA 的代码
};
public void buildPartB() {
//这里是具体如何构建partB 的代码
};
public void buildPartC() {
//这里是具体如何构建partB 的代码
};
public Product getResult() {
//返回最后组装成品结果
};
}
复杂对象:产品Product:
设计模式(Patterns in Java) --http://www.jdon.com
19
public interface Product { }
复杂对象的部件:
public interface Part { }
我们看看如何调用Builder 模式:
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );
director.construct();
Product product = builder.getResult();
Builder 模式的应用
在Java 实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,
并且这些资源需要被很多用户反复共享时,就需要使用池.
"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一
个连接会中断),如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能.修改
Builder 模式中Director 类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
具体英文文章见:Recycle broken objects in resource pools
设计模式(Patterns in Java) --http://www.jdon.com
20
设计模式之Singleton(单态)
定义:
Singleton 模式主要作用是保证在Java 应用程序中,一个Class 只有一个实例存在。
一个实例表示是单线程,在很多操作中,比如建立目录 数据库连接都需要单线程操作,
Singleton 模式经常用于控制对系统资源的控制,我们常常看到工厂模式中工厂方法也用
Singleton 模式实现的.
如何使用?
一般Singleton 模式通常有几种形式:
public class Singleton {
private static Singleton _instance = new Singleton();
public static Singleton getInstance() {
return _instance;
}
}
调用方法:
Singleton.getInstance()
第二种形式:
public class Singleton {
private static Singleton _instance = null;
public static Singleton getInstance() {
if (_instance==null)
_instancenew Singleton()
return _instance;
}
}
调用方法:
Singleton.getInstance()
设计模式(Patterns in Java) --http://www.jdon.com
21
Singleton 模式在创建对象时使用较多,使用它也比较简单。
设计模式(Patterns in Java) --http://www.jdon.com
22
设计模式之Facade(外观)
Facade 的定义: 为子系统中的一组接口提供一个一致的界面.
Facade 一个典型应用就是数据库JDBC 的应用,如下例对数据库的操作:
public class DBCompare {
Connection conn = null;
PreparedStatement prep = null;
ResultSet rset = null;
try {
Class.forName( "" ).newInstance();
conn = DriverManager.getConnection( "" );
String sql = "SELECT * FROM WHERE
1
设计模式(Patterns in Java)
Java 提供了丰富的API,同时又有强大的数据库系统作底层支持,那么我们的编程似乎
变成了类似积木的简单"拼凑"和调用,甚至有人提倡"蓝领程序员",这些都是对现代编
程技术的不了解所至.
在真正可复用的面向对象编程中,GoF 的《设计模式》为我们提供了一套可复用的面向对
象技术,再配合Refactoring(重构方法),所以很少存在简单重复的工作,加上Java 代码
的精炼性和面向对象纯洁性(设计模式是java 的灵魂),编程工作将变成一个让你时刻体
验创造快感的激动人心的过程.
为能和大家能共同探讨"设计模式",我将自己在学习中的心得写下来,只是想帮助更多
人更容易理解GoF 的《设计模式》。由于原著都是以C++为例, 以Java 为例的设计模式
基本又都以图形应用为例,而我们更关心Java 在中间件等服务器方面的应用,因此,本站
所有实例都是非图形应用,并且顺带剖析Jive 论坛系统.同时为降低理解难度,尽量避
免使用UML 图.
如果你有一定的面向对象编程经验,你会发现其中某些设计模式你已经无意识的使用过
了;如果你是一个新手,那么从开始就培养自己良好的编程习惯(让你的的程序使用通用
的模式,便于他人理解;让你自己减少重复性的编程工作),这无疑是成为一个优秀程序
员的必备条件.
整个设计模式贯穿一个原理:面对接口编程,而不是面对实现.目标原则是:降低耦合,增
强灵活性.
1:前言
学习GoF 设计模式的重要性
建筑和软件中模式之异同
2:GoF 设计模式
A.创建模式
设计模式之Factory(工厂方法和抽象工厂)
使用工厂模式就象使用new 一样频繁.
设计模式之Prototype(原型)
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的
对象。
设计模式(Patterns in Java) --http://www.jdon.com
2
设计模式之Builder
汽车由车轮 方向盘 发动机很多部件组成,同时,将这些部件组装
成汽车也是一件复杂的工作,Builder 模式就是将这两种情况分开
进行。
设计模式之Singleton(单态)
保证一个类只有一个实例,并提供一个访问它的全局访问点
B.结构模式
设计模式之Facade
可扩展的使用JDBC 针对不同的数据库编程,Facade 提供了一种灵
活的实现.
设计模式之Proxy
以Jive 为例,剖析代理模式在用户级别授权机制上的应用
设计模式之Adapter
使用类再生的两个方式:组合(new)和继承(extends),这个已经在
"thinking in java"中提到过.
设计模式之Composite
就是将类用树形结构组合成一个单位.你向别人介绍你是某单位,
你是单位中的一个元素,别人和你做买卖,相当于和单位做买卖。
文章中还对Jive 再进行了剖析。
设计模式之Decorator
Decorator 是个油漆工,给你的东东的外表刷上美丽的颜色.
设计模式之Bridge
将"牛郎织女"分开(本应在一起,分开他们,形成两个接口),在他们之
间搭建一个桥(动态的结合)
设计模式之Flyweight
提供Java 运行性能,降低小而大量重复的类的开销.
C.行为模式
设计模式之Template
实际上向你介绍了为什么要使用Java 抽象类,该模式原理简单,使
用很普遍.
设计模式之Memento
很简单一个模式,就是在内存中保留原来数据的拷贝.
设计模式之Observer
介绍如何使用Java API 提供的现成Observer
设计模式(Patterns in Java) --http://www.jdon.com
3
设计模式之Chain of Responsibility
各司其职的类串成一串,好象击鼓传花,当然如果自己能完成,就不
要推委给下一个.
设计模式之Command
什么是将行为封装,Command 是最好的说明.
设计模式之State
状态是编程中经常碰到的实例,将状态对象化,设立状态变换器,便
可在状态中轻松切换.
设计模式之Strategy
不同算法各自封装,用户端可随意挑选需要的算法.
设计模式之Mediator
Mediator 很象十字路口的红绿灯,每个车辆只需和红绿灯交互就可
以.
设计模式之Interpreter
主要用来对语言的分析,应用机会不多.
设计模式之Visitor
访问者在进行访问时,完成一系列实质性操作,而且还可以扩展.
设计模式之Iterator
这个模式已经被整合入Java 的Collection.在大多数场合下无需自
己制造一个Iterator,只要将对象装入Collection中,直接使用Iterator
进行对象遍历。
3:英文资料
Thinking in Patterns with Java Thinking in Java 的作者Eckel 又一
著作!
CMSC491D Design Patterns In Java
Overview of Design Patterns 精确定义各个模式以及他们的关系
Design Patterns Java Companion
EJB 设计模式(英文) 从设计模式去理解EJB 或J2EE我认为是个非常有效
的办法.
设计模式(Patterns in Java) --http://www.jdon.com
4
学习GoF 设计模式的重要性
GoF 的《设计模式》也许你没有听说过,但是《Thingking in Java》(Java 编程思想)你应该
知道甚至读过吧!
在浏览《Thingking in Java》(第一版)时,你是不是觉得好象这还是一本Java 基础语言书
籍?但又不纯粹是,因为这本书的作者将面向对象的思想巧妙的融合在Java 的具体技术上,
潜移默化的让你感觉到了一种新的语言和新的思想方式的诞生。
但是读完这本书,你对书中这些蕴含的思想也许需要一种更明晰更系统更透彻的了解和掌
握,那么你就需要研读GoF 的《设计模式》了。
《Thingking in Java》(第一版中文)是这样描述设计模式的:他在由Gamma, Helm 和Johnson
Vlissides 简称Gang of Four(四人帮),缩写GoF 编著的《Design Patterns》一书中被定义
成一个“里程碑”。事实上,那本书现在已成为几乎所有OOP(面向对象程序设计)程序员都
必备的参考书。(在国外是如此)。
GoF 的《设计模式》是所有面向对象语言(C++ Java C#)的基础,只不过不同的语言将之实
现得更方便地使用。
GOF 的设计模式是一座"桥"
就Java 语言体系来说,GOF 的设计模式是Java 基础知识和J2EE 框架知识之间一座隐性的"
桥"。
会Java 的人越来越多,但是一直徘徊在语言层次的程序员不在少数,真正掌握Java 中接口
或抽象类的应用不是很多,大家经常以那些技术只适合大型项目为由,避开或忽略它们,实
际中,Java 的接口或抽象类是真正体现Java 思想的核心所在,这些你都将在GoF 的设计模
式里领略到它们变幻无穷的魔力。
GoF 的设计模式表面上好象也是一种具体的"技术",而且新的设计模式不断在出现,设计模
式自有其自己的发展轨道,而这些好象和J2EE .Net 等技术也无关!
实际上,GoF 的设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或
抽象类在实际案例中的灵活应用和智慧,让你能够真正掌握接口或抽象类的应用,从而在原
来的Java 语言基础上跃进一步,更重要的是,GoF 的设计模式反复向你强调一个宗旨:要
让你的程序尽可能的可重用。
这其实在向一个极限挑战:软件需求变幻无穷,计划没有变化快,但是我们还是要寻找出不
变的东西,并将它和变化的东西分离开来,这需要非常的智慧和经验。
而GoF 的设计模式是在这方面开始探索的一块里程碑。
设计模式(Patterns in Java) --http://www.jdon.com
5
J2EE 等属于一种框架软件,什么是框架软件?它不同于我们以前接触的Java API 等,那些
属于Toolkist(工具箱),它不再被动的被使用,被调用,而是深刻的介入到一个领域中去,
J2EE 等框架软件设计的目的是将一个领域中不变的东西先定义好,比如整体结构和一些主
要职责(如数据库操作 事务跟踪 安全等),剩余的就是变化的东西,针对这个领域中具体应
用产生的具体不同的变化需求,而这些变化东西就是J2EE 程序员所要做的。
由此可见,设计模式和J2EE 在思想和动机上是一脉相承,只不过
1.设计模式更抽象,J2EE 是具体的产品代码,我们可以接触到,而设计模式在对每个应用
时才会产生具体代码。
2.设计模式是比J2EE 等框架软件更小的体系结构,J2EE 中许多具体程序都是应用设计模式
来完成的,当你深入到J2EE 的内部代码研究时,这点尤其明显,因此,如果你不具备设计
模式的基础知识(GoF 的设计模式),你很难快速的理解J2EE。不能理解J2EE,如何能灵活应
用?
3.J2EE 只是适合企业计算应用的框架软件,但是GoF 的设计模式几乎可以用于任何应用!
因此GoF 的设计模式应该是J2EE 的重要理论基础之一。
所以说,GoF 的设计模式是Java 基础知识和J2EE 框架知识之间一座隐性的"桥"。为什么说
隐性的?
GOF 的设计模式是一座隐性的"桥"
因为很多人没有注意到这点,学完Java 基础语言就直接去学J2EE,有的甚至鸭子赶架,直
接使用起Weblogic 等具体J2EE 软件,一段时间下来,发现不过如此,挺简单好用,但是你
真正理解J2EE 了吗?你在具体案例中的应用是否也是在延伸J2EE 的思想?
如果你不能很好的延伸J2EE 的思想,那你岂非是大炮轰蚊子,认识到J2EE 不是适合所有场
合的人至少是明智的,但我们更需要将J2EE 用对地方,那么只有理解J2EE 此类框架软件的
精髓,那么你才能真正灵活应用Java 解决你的问题,甚至构架出你自己企业的框架来。(我
们不能总是使用别人设定好的框架,为什么不能有我们自己的框架?)
因此,首先你必须掌握GoF 的设计模式。虽然它是隐性,但不是可以越过的。
在著名的EJB 领域顶尖的专家Richard Monson-Haefel 的个人网站:www.EJBNow.com 中
Richard 极力推荐的几本书中就有GoF 的《设计模式》,原文如下:
Design Patterns
Most developers claim to experience an epiphany reading this book. If you‘ve never
read the Design Patterns book then you have suffered a very serious gap in your
programming education that should be remedied immediately.
翻译: 很多程序员在读完这本书,宣布自己相当于经历了一次"主显节"(纪念那稣降生和受
洗的双重节日),如果你从来没有读过这本书,你会在你的程序教育生涯里存在一个严重裂沟,
所以你应该立即挽救弥补!
设计模式(Patterns in Java) --http://www.jdon.com
6
设计模式(Patterns in Java) --http://www.jdon.com
7
建筑和软件中模式之异同
CSDN 的透明特别推崇《建筑的永恒之道》,认为从中探寻到软件的永恒之道,并就"设计模式
"写了专门文章《探寻软件的永恒之道 》,其中很多观点我看了很受启发,以前我也将"设计
模式" 看成一个简单的解决方案,没有从一种高度来看待"设计模式"在软件中地位,下面是
我自己的一些想法:
建筑和软件某些地方是可以来比喻的
特别是中国传统建筑,那是很讲模式的,这些都是传统文化使然,比如京剧 一招一式都有套
路;中国画,也有套路,树应该怎么画法?有几种画法?艺术大家通常是创造出自己的套路,比
如明末清初,水墨画法开始成熟,这时画树就不用勾勒这个模式了,而是一笔下去,浓淡几个
叶子,待毛笔的水墨要干枯时,画一下树干,这样,一个活生写意的树就画出来.
我上面这些描述其实都是一种模式,创建模式的人是大师,但是拘泥于模式的人永远是工匠.
再回到传统建筑中,中国的传统建筑是过分注重模式了,所以建筑风格发展不大,基本分南北
两派,大家有个感觉,旅游时,到南方,你发现古代名居建筑都差不多;北方由于受满人等少数
民族的影响,在建筑色彩上有些与南方迥异,但是很多细节地方都差不多.这些都是模式的体
现.
由于建筑受材料和功用以及费用的影响,所用模式种类不多,这点是和软件很大的不同.
正因为这点不同,导致建筑的管理模式和软件的管理模式就有很多不同, 有些人认识不到这
点,就产生了可以大量使用"软件蓝领"的想法,因为他羡慕建筑中"民工"的低成本.
要知道软件还有一个与建筑截然相反的责任和用途,那就是:现代社会中,计划感不上变化,
竞争激烈,所有一切变幻莫测,要应付所有这些变化,首推信息技术中的软件,只有软件能够
帮助人类去应付各种变化.而这点正好与建筑想反,建筑是不能帮助人类去应付变化的,(它
自己反而要求稳固,老老实实帮助人遮风避雨,总不能叫人类在露天或树叶下打开电脑编软
件吧).
软件要帮助人类去应付变化,这是软件的首要责任,所以,软件中模式产生的目的就和建筑不
一样了,建筑中的模式产生可以因为很多原因:建筑大师的创意;材料的革新等;建筑中这些
模式一旦产生,容易发生另外一个缺点,就是有时会阻碍建筑本身的发展,因为很多人会不思
创造,反复使用老的模式进行设计,阻碍建筑的发展.
但是在软件中,这点正好相反,软件模式的产生是因为变化的东西太多,为减轻人类的负担,
将一些不变的东西先用模式固化,这样让人类可以更加集中精力对付变化的东西,所以在软
件中大量反复使用模式(我个人认为这样的软件就叫框架软件了,比如J2EE),不但没阻碍软
件的发展,反而是推动了软件的发展.因为其他使用这套软件的人就可以将更多精力集中在
对付那些无法用模式的应用上来.
设计模式(Patterns in Java) --http://www.jdon.com
8
可以关于建筑和软件中的模式作用可以总结如下:
在软件中,模式是帮助人类向"变化"战斗,但是在软件中还需要和‘变化‘直接面对面战斗的
武器:人的思维,特别是创造 分析思维等等,这些是软件真正的灵魂,这种思维可以说只要
有实践需求(如有新项目)就要求发生,发生频度高,人类的创造或分析思维决定了软件的质
量和特点。
而在建筑中,模式可以构成建筑全部知识,当有新的需求(如有新项目),一般使用旧的模式
都可以完成,因此对人类的创造以及分析思维不是每个项目都必须的,也不是非常重要的,
对创造性的思维的需求只是属于锦上添花(除非人类以后离开地球居住了)。
设计模式(Patterns in Java) --http://www.jdon.com
9
设计模式之Factory
定义:提供创建对象的接口.
为何使用?
工厂模式是我们最常用的模式了,著名的Jive 论坛系统,就大量使用了工厂模式.
为什么说工厂模式是最常用,因为工厂模式就相当于创建对象的new. 工厂模式就是用来创
建对象的.
比如我们有一个类Sample 我们要创建Sample 的对象:
Sample sample=new Sample();
如果我们要在创建sample 之前做点事情,比如,赋值等,可以使用Sample 的构造函数:
Sample sample=new Sample(参数);
如果创建sample 时做的事情不是如赋值这样简单的事,可能是很长一段代码,如果也写入构
造函数中,那明显的就违背了面向对象的原则.封装(Encapsulation)和分派(Delegation);
我们需要将创建实例的责任与使用实例的责任分开, 使得语句
Sample sample=new Sample(参数);
就是简单的责任:使用Sample 这个实例;至于创建Sample 的任务就交给了Factory 工厂模
式.
还有,如果Sample 有个继承如MySample, 按照面向接口编程,我们需要将Sample 抽象成一
个接口.
现在Sample 是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:
Sample mysample=new MySample();
Sample hissample=new HisSample();
随着项目的深入,Sample 可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实
例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程
序中是无法避免的.
但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
你会建立一个专门生产Sample 实例的工厂:
设计模式(Patterns in Java) --http://www.jdon.com
10
public class Factory{
public static Sample creator(){
....
if (which==1)
return new MySample();
else if (which==2)
return new HisSample();
}
}
那么在你的程序中,如果要实例化MySample 时.就使用
Sample sample=Factory.creator();
这样,在整个就不涉及到Sample 的具体子类,达到封装效果,也就减少错误修改的机会,这个
原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误.这每个做过具体工作
的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,范错误可能性就越少.好象我们
从编程序中也能悟出人生道理?呵呵.
好了,言归正传,既然不可避免使用factory,那我们就认识一下工厂模式.
如何使用?
工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
上例中,我们使用的是简单的工厂方法. 这两个模式没有很明显的区别,区别在于需要创建
对象的复杂程度上。如果我们创建对象的方法变得复杂了,我们就可能要将上例中Factory
变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现:
public abstract class Factory{
public abstract Sample creator();
public abstract Sample2 creator();
}
public class SimpleFactory extends Factory{
public Sample creator(){
设计模式(Patterns in Java) --http://www.jdon.com
11
......
}
public Sample2 creator(){
......
}
}
public class BombFactory extends Factory{
public Sample creator(){
......
}
public Sample2 creator(){
......
}
}
上例中我们只有一类产品接口 Sample , 工厂方法和抽象工厂可以创建多个产品接口的实
例,比如Sample2 Sample3
FactoryMethod 往往只是创建单个的实例。Abstract Factory 创建一系列的实例组,这些实
例彼此相关。
举例1
下图是来自天极网" 阎宏"的 爪哇语言抽象工厂创立性模式介绍 中的抽象工厂图:
设计模式(Patterns in Java) --http://www.jdon.com
12
在这张图中, 有两类产品接口interface RAM 和interface CPU; 同时有两个创建方
法:MacProducer 和PCProducer,这两个创建方法中都有createCPU()和createRAM(),返回的
实例对象组是CPU 和RAM, 这是分别来自两类产品接口,表面彼此是相关的.因此它是抽象工
厂.
举例2
我们以Jive 的ForumFactory 为例:
public abstract class ForumFactory {
private static Object initLock = new Object();
private static String className =
"com.jivesoftware.forum.database.DbForumFactory";
private static ForumFactory factory = null;
public static ForumFactory getInstance(Authorization authorization) {
//If no valid authorization passed in, return null.
if (authorization == null) {
return null;
}
//以下使用了Singleton 单态模式
if (factory == null) {
synchronized(initLock) {
if (factory == null) {
设计模式(Patterns in Java) --http://www.jdon.com
13
......
try {
//动态转载类
Class c = Class.forName(className);
factory = (ForumFactory)c.newInstance();
}
catch (Exception e) {
return null;
}
}
}
}
//Now, 返回 proxy.用来限制授权对forum 的访问
return new ForumFactoryProxy(authorization, factory,
factory.getPermissions(authorization));
}
//真正创建forum 的方法由继承forumfactory 的子类去完成.
public abstract Forum createForum(String name, String description)
throws UnauthorizedException, ForumAlreadyExistsException;
....
}
因为现在的Jive 是通过数据库系统存放论坛帖子等内容数据,如果有人要扩展为纯粹的文
件系统存放的论坛帖子,这个工厂方法ForumFactory 就提供了提供动态接口:
private static String className =
"com.jivesoftware.forum.database.DbForumFactory";
你可以使用自己开发的创建forum 的方法代替
com.jivesoftware.forum.database.DbForumFactory 就可以.
在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Singleton 单态模式,以及
proxy 模式,proxy 模式主要用来授权用户对forum 的访问,因为访问forum有两种人:一个是
注册用户 一个是游客guest,那么那么相应的权限就不一样,而且这个权限是贯穿整个系统
的,因此建立一个proxy,类似网关的概念,可以很好的达到这个效果.
设计模式(Patterns in Java) --http://www.jdon.com
14
好了.经过上述简单描述,你对工厂模式应该有个简单的印象,如果你要钻研工厂模式,网络
上有很多英文资料,不过我觉得过分钻研也没有必要,主要是使用实践,实际使用中工厂模式
的变种很多,只要你知道这样一个大概思路,相信在实践中你会是工厂模式的设计创建高手!
设计模式(Patterns in Java) --http://www.jdon.com
15
设计模式之Prototype(原型)
定义:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.
Prototype 模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的
细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象
通过请求原型对象拷贝它们自己来实施创建。
如何使用?
因为Java 中的提供clone()方法来实现对象的克隆(具体了解clone()按这里),所以
Prototype 模式实现一下子变得很简单.
以勺子为例:
public abstract class AbstractSpoon implements Cloneable
{
String spoonName;
public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
public String getSpoonName() {return this.spoonName;}
public Object clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractSpoon is not Cloneable");
}
return object;
}
}
有两个具体实现(ConcretePrototype):
public class SoupSpoon extends AbstractSpoon
{
public SoupSpoon()
{
setSpoonName("Soup Spoon");
设计模式(Patterns in Java) --http://www.jdon.com
16
}
}
public class SaladSpoon extends AbstractSpoon
{
public SaladSpoon()
{
setSpoonName("Salad Spoon");
}
}
调用Prototype 模式很简单:
AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon = new SaladSpoon();
当然也可以结合工厂模式来创建AbstractSpoon 实例。
在Java 中Prototype 模式变成clone()方法的使用,由于Java 的纯洁的面向对象特性,使
得在Java 中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,
如Interator 遍历模式。
设计模式(Patterns in Java) --http://www.jdon.com
17
设计模式之Builder
Builder 模式定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
Builder 模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型
和内容就可以构建它们.用户不知道内部的具体构建细节.Builder 模式是非常类似抽象工
厂模式,细微的区别大概只有在反复使用中才能体会到.
为何使用?
是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮 方向盘 发动机
还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一辆汽车,这个装配
过程也很复杂(需要很好的组装技术),Builder 模式就是为了将部件和组装过程分开.
如何使用?
首先假设一个复杂对象是由多个部件组成的,Builder 模式是把复杂对象的创建和部件的创
建分别开来,分别用Builder 类和Director 类来表示.
首先,需要一个接口,它定义如何创建复杂对象的各个部件:
public interface Builder {
//创建部件A 比如创建汽车车轮
void buildPartA();
//创建部件B 比如创建汽车方向盘
void buildPartB();
//创建部件C 比如创建汽车发动机
void buildPartC();
//返回最后组装成品结果 (返回最后装配好的汽车)
//成品的组装过程不在这里进行,而是转移到下面的Director 类中
进行.
//从而实现了解耦过程和部件
Product getResult();
}
用Director 构建最后的复杂对象,而在上面Builder 接口中封装的是如何创建一个个部件
(复杂对象是由这些部件组成的),也就是说Director 的内容是如何将部件最后组装成成品:
设计模式(Patterns in Java) --http://www.jdon.com
18
public class Director {
private Builder builder;
public Director( Builder builder ) {
this.builder = builder;
}
// 将部件partA partB partC 最后组成复杂对象
//这里是将车轮 方向盘和发动机组装成汽车的过程
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
Builder 的具体实现ConcreteBuilder:
通过具体完成接口Builder 来构建或装配产品的部件;
定义并明确它所要创建的是什么具体东西;
提供一个可以重新获取产品的接口:
public class ConcreteBuilder implements Builder {
Part partA, partB, partC;
public void buildPartA() {
//这里是具体如何构建partA 的代码
};
public void buildPartB() {
//这里是具体如何构建partB 的代码
};
public void buildPartC() {
//这里是具体如何构建partB 的代码
};
public Product getResult() {
//返回最后组装成品结果
};
}
复杂对象:产品Product:
设计模式(Patterns in Java) --http://www.jdon.com
19
public interface Product { }
复杂对象的部件:
public interface Part { }
我们看看如何调用Builder 模式:
ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );
director.construct();
Product product = builder.getResult();
Builder 模式的应用
在Java 实际使用中,我们经常用到"池"(Pool)的概念,当资源提供者无法提供足够的资源,
并且这些资源需要被很多用户反复共享时,就需要使用池.
"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(比如数据库的连接池,也许有时一
个连接会中断),如果循环再利用这些"断肢",将提高内存使用效率,提高池的性能.修改
Builder 模式中Director 类使之能诊断"断肢"断在哪个部件上,再修复这个部件.
具体英文文章见:Recycle broken objects in resource pools
设计模式(Patterns in Java) --http://www.jdon.com
20
设计模式之Singleton(单态)
定义:
Singleton 模式主要作用是保证在Java 应用程序中,一个Class 只有一个实例存在。
一个实例表示是单线程,在很多操作中,比如建立目录 数据库连接都需要单线程操作,
Singleton 模式经常用于控制对系统资源的控制,我们常常看到工厂模式中工厂方法也用
Singleton 模式实现的.
如何使用?
一般Singleton 模式通常有几种形式:
public class Singleton {
private static Singleton _instance = new Singleton();
public static Singleton getInstance() {
return _instance;
}
}
调用方法:
Singleton.getInstance()
第二种形式:
public class Singleton {
private static Singleton _instance = null;
public static Singleton getInstance() {
if (_instance==null)
_instancenew Singleton()
return _instance;
}
}
调用方法:
Singleton.getInstance()
设计模式(Patterns in Java) --http://www.jdon.com
21
Singleton 模式在创建对象时使用较多,使用它也比较简单。
设计模式(Patterns in Java) --http://www.jdon.com
22
设计模式之Facade(外观)
Facade 的定义: 为子系统中的一组接口提供一个一致的界面.
Facade 一个典型应用就是数据库JDBC 的应用,如下例对数据库的操作:
public class DBCompare {
Connection conn = null;
PreparedStatement prep = null;
ResultSet rset = null;
try {
Class.forName( "
conn = DriverManager.getConnection( "
String sql = "SELECT * FROM