??xml version="1.0" encoding="utf-8" standalone="yes"?> 虽然q是菜鸟,但既然看q了设计模式Q还是希望能用v来的?/p>
惛_个自p乐的j2ee的东ѝ?/p>
关于得到数据库连接部分,一开始觉得是用工厂模式,用工厂模式得到Connection对象Q试了几ơ好像不行?/p>
然后试单态模式,创造了一个DatabaseGeneralServicesc,来提供数据库q接和关闭数据库{一些通用的服务?br />
一切正常。有点小感?zhn)Q代码如下,希望高手指点?/p>
package com.ClockWise.ray.persistence; import java.sql.Connection; import javax.naming.InitialContext; public class DatabaseGeneralServices { }
_粗看完一遍设计模式的时候,觉得Builder Pattern和Factory Method Pattern有点hQ好像这两者都是将复杂的构造过E屏蔽掉Q最l返回一个Client满意的对象,但他们的本质是不一L(fng)?br />
Builder Pattern只针对一个类Q这个类的特Ҏ(gu)构造v来过E特别复杂,所以将构造的部分独立出来Q专门用一个BuilderClass来负责生成对象?br />
Factory Method更多的是针对生成实现同一接口的一l类中的某个。有Ҏ(gu)口,是在运行时生成正确的对象?br />
ȝ下来Q就是Builder针对一个ClassQFactory Method针对从一lClass中挑选一?/span>?/span>
]]>
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.naming.NamingException;
import javax.sql.DataSource;
private DataSource ds;
private InitialContext ic;
private static DatabaseGeneralServices dgs = new DatabaseGeneralServices();
private DatabaseGeneralServices()//use singleton pattern, so the constructor is private
{
try{
ic = new InitialContext ();
ds = (DataSource)ic.lookup("java:jdbc/readshare");//get database connection
}catch(NamingException e){
e.printStackTrace();
}
}
public Connection getConnection(){
try{
return ds.getConnection();
}catch(SQLException e){
e.printStackTrace();
}
return null;
}
public void closeConnection(ResultSet rs,PreparedStatement ps,Connection conn){
try{
if(rs!=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
}catch(SQLException e ){
e.printStackTrace();
}
}
public static DatabaseGeneralServices getInstance()//get the sigleton instance
{
if(null==dgs){dgs= new DatabaseGeneralServices();}
return dgs;
}
]]>
从这个模式的名字可以知道个大概Q?/span>Template说明q个模式有一个模版,子类都要按照父类列出的大U来q活。在q个模式中,父类通常?/span>abstract的。ؓ(f)什么不用接口?因ؓ(f)Ҏ(gu)些所有子c都要用到的Ҏ(gu)Q父cMqZ代码Q而接口中是不能有具体实现代码的?/span>
父类中有一个ȝҎ(gu)是所谓的template methodQ这个方法通常被声明ؓ(f)finalQ这样子cd无法override它,保证了它的权威性。这?/span>template method调用其它Ҏ(gu)Q这?#8220;其它Ҏ(gu)”包括了三个类型:(x)
W一U,?/span>abstractcdQ子c需要根据自q情况实现q部分代码;
W二U,?/span>final型的Q这U方法父cL它写MQ子cd遵守;
W三U,是普通方法,?/span>optional?/span>Q子cd以g用父cȝҎ(gu)Q也可以override掉它Q写自己的代码,q种optional的方法给它一个名字叫?/span>hook?/span>
q个父类通常是这UŞѝ?/span>
abstract class AbstractClass{
final void templateMethod(){
a();
b();
c();
…
}
abstract void a();
final void b(){}
void c(){}
}
应该说这个模式既蕴含着权威性和自由性?/span>
Iterator and Composite Patterns
q个模式的研I对象是CollectionQ包?/span>ArrayList?/span>Array甚至q有Hashmap{等一?/span>java里面的集合对象?/span>Iterator的理忉|把集合对象中的遍历等功能独立抽取出来Q实C?/span>Iterator的接口,主要实现nextQ)(j)?/span>hasNextQ)(j)两个Ҏ(gu)Q这些东西和数据l构里面的东西基本一栗?/span>
而以此ؓ(f)基础?/span>Composite Pattern其实是数据l构里面?wi)的概念Q所以这里的东西q是找本数据l构书看看更好?/span>
The State Pattern
初看q个模式Q发现里面有一个类?/span>UML中状态图的东西,如其名字Q这个模式主要描q如何处理应用中出现?#8220;状?#8221;?/span>
解决方式是这L(fng)Q?/span>
. W一步,创徏一个叫?/span>State的接?/span>Q里面包含什么东西呢Q记?/span>UML状态图中发生状态{换时头上面那些改变的条Ӟ把这些条件全部{化ؓ(f)Ҏ(gu)Q表C当q个条g发生Ӟ状态该怎么变?/span>
W二步,每个具体?/span>concreteState都要实现都要实现Stateq个接口。怎么实现Q当?dng)?/span>state不是独立出现的,L一个把它作为参数的c,里面有个U有变量保存当前的状态,暂且把它称?/span>currentState吧。接口中定义的方法,?/span>concreteState中这样实玎ͼ(x)每个Ҏ(gu)Ҏ(gu)条g定义Q将currentStateҎ(gu)相应的状态?/span>
以上其实是State Pattern的精髓?/span>
Singleton Pattern
针对一些在应用中只?x)有一个对象存在的c而ȝ的模式?/span>
令h意想不到的是Q它是通过声明该类的构造函Cؓ(f)U有q种Ҏ(gu)来实现的?/span>
疑问是Q既然构造函数都成私有了Q那怎么来创个类的对象呢Q?/span>
解答是通过在类中声明一个静态方法,q回q个对象?/span>
典型的写法是
public static Singleton getInstance(){
if(uniqueInstance==null){uniqueInstance = new Singleton();}
return uniqueInstance;
}
q个模式的精髓就q么单,剩下的就是线E对对象的操作安全,要把q个Ҏ(gu)加上synchronized关键字?/span>
Command Pattern
书中是以馆点菜作比来讲q这个模式的?/span>
其中的对比概念如?/span>
Customer-------Client
Order------------Command
Waitress--------Invoker
Cook------------Receiver
Take order--------setCommand
orderUp-----------excute
怎么来解释呢Q说白了Q就是把调用c要达成的操作封装成一?/span>Command对象Q就像点菜那张单子一P当然q个Command要符合一定的规则实现Command接口Q里面非帔R要的一个方法就?/span>execute?/span>
setCommandҎ(gu)相当?/span>waitress把菜单递给了厨师,在接收者方面他只管q行executeQ具体做什么传q来?/span>command对象都已l设定好了?/span>
Adapter & Façade
适配器模式其实没什么多说的Q就是要把传q去的对象要实现接收者支持的格式Q那个格式实际上是一个接口?/span>
?/span>Façade模式是一U衍生物Q它的目的是让操作简单化。将一pd不同对象中的操作整合Q提供给其它c调用接口书上的例子是家庭媄(jing)院,要看部电(sh)影,要开q个?sh)器Q开那个?sh)器Q通过Façade模式Q将要看?sh)?jing)所必须的动作整合v来,一键搞定。明白了q点Q也q解了q个模式?/span>
Factory Pattern
书中举了匹萨店的例子Q一开始的c,制作不同类型匹萨的Ҏ(gu)都包含在里面Q整个类昑־很冗余。顺着正常的思\Q将制作匹萨的方法从q个c里面剥dd独Ş成一个类Q这个类像生对象的工厂,只要你告诉它该生产的产品的型P它就生对应的对象再发送给客户?/span>
按照书中的例子,如果匹萨店开在同一个城市以内,匹萨的风呛_P那么上述的模式很好地实现了上面的功能。但如果是连锁店Q每个地方的风味不同呢?……
是的Q每个地方的风味不同Q但同一个地方不同匹萨的U类却相当有限。也是说可以有一个匹萨店父类Q然后各地的分店是这个父cȝ子类。而其中最重要的制作匹萨的Ҏ(gu)在父cM被声明ؓ(f)虚函敎ͼ由各个具体的子类来实现。这?#8220;工厂”又被搬回具体的类中间?/span>
具体如何使用Q我个h觉得是要看情늚。上面两个是工厂模式的两U表现Ş式?/span>
对于后一U模式,里面用到的对象,比如例子中匹萨的原材料,同样可以用工厂模式来实现Q这L(fng)序的l构q当灵zM?/span>
其中?#8220;一”Q类g定报U系l的发送方Q?#8220;?#8221;是订阅斏V当有新?#8220;报纸”Ӟ发送方最新的报纸送达订阅Ҏ(gu)中。发送方l护着一个订阅方的列表?/span>
文中通过一个气象站的例子来解说q个模式?/span>WeatherData实现Subject接口Q里面包括所要传送的private 数据Q还有注?/span>Observer和去?/span>Observer的方法。当数据有所更新时调?/span>measurementChangedҎ(gu)Q这个方法再调用notifyObserversҎ(gu)?/span>
而在Observer那端Q有一?/span>subject对象的私有数据,通过构造函数将要注册的Subject作ؓ(f)参数来对它进行初始化Q以此徏?/span>Observer?/span>Subject的联pR?/span>
最后还介绍?/span>java那徏?/span>Observer模式。通过l承Observable来成?/span>SubjectQ通过实现Observer接口来成?/span>Observer。但其有一定弊病,因ؓ(f)java不支持多l承Q这限制了使用q个模式的灵zL。所以我觉得以后如果真的用到Observer模式q是自己~程比较好?/span>
以前已经看过两章了,实在太过久远Q只得重温一下?/span>
前面?/span> Introduction 其实是非常有意思的Q在q先不赘qC?/span>
介绍的第一?/span> Pattern ?/span> Strategy Pattern ?/span>
通过一?/span> duck 的例子,在讲q?/span> Strategy Pattern 的过E中引出了三?/span> Design Principles
它们是:(x)
1Q?span style="FONT: 7pt 'Times New Roman'">
Identify the aspects of your application that vary and separate them from what stays the same.
2Q?span style="FONT: 7pt 'Times New Roman'">
Program to an interface, not an implementation.
3Q?span style="FONT: 7pt 'Times New Roman'">
Favor composition over inheritance.
Duck 例子完美CC以上三个 Principles ?/span>
一开?/span> Duck cLq样的,里面有三个方法:(x) quack(), swim() ?/span> display(), 其它一些特D的 Duck 子类l承q个父类Qƈ重蝲 display Ҏ(gu)LC各U不同种cȝ Duck ?/span>
现在需求变_(d)需要让一?/span> Duck 能够有飞的能力,理所当然圎ͼ在父cM加上?/span> fly() q个Ҏ(gu)。但一些不能飞?/span> Duck cd同时拥有?/span> fly() Ҏ(gu)Q这昄是不对的?/span>
可能有h提出解决的方法是重蝲那些不需?/span> fly() Ҏ(gu)?/span> duck cȝ fly() Q让q个Ҏ(gu)什么也不做Q但你有没有惌如果q么处理Q以后再加一些不需要一些方法的子类是不是很J琐Q?/span>
也许又有人想CQ把 fly() ?/span> quack() 提取出来Q编E?/span> interface 。如果某个子c需要这个能力可以去 implement q个 interface ?/span>
有没有想q后果?每一个子c都要重?/span> fly() ?/span> quack(),OO 的代码重用的Ҏ(gu)荡然无存?/span>
那什么才是最好的解决之道呢?Q?
书里面给Z{案?/span>
?/span> fly() ?/span> quack() 两个功能提取出来q个思\是对的?b style="mso-bidi-font-weight: normal">q里体现了第一?/span> Principle 。首先声?/span> FlyBehavior() ?/span> QuackBehavior() 两个 interface Q然后实现各U?/span> fly ?/span> quack Q比?/span> FlyWithWings, FlyNoWay Q?/span> Quack, Squeak {等?b style="mso-bidi-font-weight: normal">q里体现了第二个 Principle ?/span>
现在?/span> Duck 父类已经变了Q里面有两个U有变量 FlyBehavior fb, ?/span> QuackBehavior qb ?/span>
Duck 父类甚至可以直接声明?/span> Abstract c,当有子类l承它的时候,可以在构造函数里l?/span> fb ?/span> qb 初始化的时候直接赋l它需要的 fly ?/span> quack U类?b style="mso-bidi-font-weight: normal">q里体现了第三个 Principle ?/span>
小的一个例子已l分析的那么专业Q让我受益匪。好书!