Java与模式.docx
- 文档编号:6059513
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:29
- 大小:351.19KB
Java与模式.docx
《Java与模式.docx》由会员分享,可在线阅读,更多相关《Java与模式.docx(29页珍藏版)》请在冰豆网上搜索。
Java与模式
Java与模式
1工厂模式专门负责将大量有共同接口的类实例化。
工厂模式可以动态决定将哪一个类
实例化,不必事先知道每次要实例化哪一个类。
工厂模式有以下几种形态:
(1)简单工厂(SimpleFactory)模式,又称静态工厂方法模式(StaticFactoryMethodPattern)。
(2)工厂方法(FactoryMethod)模式,又称多态性工厂(PolymorphicFactory)模式或虚拟构造子(VirtualConstructor模式;
(3)抽象工厂(AbstractFactory)模式,又称工具箱(Kit或Toolkit)模式。
1)简单工厂(SimpleFactory)模式,简单工厂模式是类的创建模式,又叫做静态工厂方法(StaticFactoryMethod)模式。
简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。
其实简单工厂模式就是由一个工厂类可以根据传入的参量决定创建出哪一种产品类的实例
实例:
有三种水果,他们的父接口就是fruit
葡萄Grape
草莓Strawberry
苹果Apple
publicclassFruitGardener
{
/**
*静态工厂方法
*/
publicstaticFruitfactory(Stringwhich)throwsBadFruitException
{if(which.equalsIgnoreCase("apple")){
returnnewApple();
}
elseif(which.equalsIgnoreCase("strawberry")){
returnnewStrawberry();
}
elseif(which.equalsIgnoreCase("grape")){
returnnewGrape();
}else{thrownewBadFruitException("Badfruitrequest");
}
}
}
在使用时,客户端只需调用FruitGardener的静态方法factory()即可
2)工厂方法(FactoryMethod)模式工厂方法模式是类的创建模式,又叫做虚拟构造子(VirtualConstructor)模式或者多
态性工厂(PolymorphicFactory)模式。
工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子
类中。
工厂方法模式是简单工厂模式的进一步抽象和推广。
由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点
首先,在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。
这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
这种进一步抽象化的结果,使这种工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品,这一特点无疑使得工厂模式具有超过简单工厂模式的优越性。
1:
抽象工厂角色Creator类的源代码
packagecom.javapatterns.factorymethod;
publicinterfaceCreator{
/***工厂方法*/
publicProductfactory();
}
抽象产品角色Product类的源代码
packagecom.javapatterns.factorymethod;
publicinterfaceProduct
{
}
3:
具体工厂角色ConcreteCreator1类的源代码
packagecom.javapatterns.factorymethod;
publicclassConcreteCreator1implementsCreator
{
/***工厂方法*/
publicProductfactory(){
returnnewConcreteProduct1();
}
}
具体工厂角色ConcreteCreator2类的源代码
packagecom.javapatterns.factorymethod;
publicclassConcreteCreator2implementsCreator{
/***工厂方法*/
publicProductfactory(){
returnnewConcreteProduct2();
}
}
具体产品角色ConcreteProduct1类的源代码
packagecom.javapatterns.factorymethod;
publicclassConcreteProduct1implementsProduct{
publicConcreteProduct1(){
//dosomething
}
}
具体产品角色ConcreteProduct2类的源代码
packagecom.javapatterns.factorymethod;
publicclassConcreteProduct2implementsProduct{
publicConcreteProduct2(){
//dosomething
}
}
客户端角色Client类的源代码
packagecom.javapatterns.factorymethod;
publicclassClient{
privatestaticCreatorcreator1,creator2;
privatestaticProductprod1,prod2;
publicstaticvoidmain(String[]args){
creator1=newConcreteCreator1();
prod1=creator1.factory();
creator2=newConcreteCreator2();
prod2=creator2.factory();
}
}
注意:
工厂方法模式在农场系统中的实现图
3)抽象工厂(AbstractFactory)模式抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
它是工厂方法模式的进一步推广。
抽象工厂模式的简略类图如下所示。
★左边的等级结构代表工厂等级结构,右边的两个等级结构分别代表两个不同的产品的
等级结构。
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的
具体类型的情况下,创建多个产品族中的产品对象。
这就是抽象工厂模式的用意。
实例
源代码
下面给出这个系统所有的源代码。
首先给出工厂角色的源代码,可以看出,抽象工厂角色规定出两个工厂方法,分别提供两个不同等级结构的产品对象。
代码清单1:
抽象产品角色的源代
packagecom.javapatterns.abstractfactory;
publicinterfaceCreator{
/**
*产品等级结构A的工厂方法
*/
publicProductAfactoryA();
/**
*产品等级结构B的工厂方法
*/
publicProductBfactoryB();
}
具体工厂类ConcreteCreator1的源代码
packagecom.javapatterns.abstractfactory;
publicclassConcreteCreator1implementsCreator
{
/**
*产品等级结构A的工厂方法
*/
publicProductAfactoryA(){
returnnewProductA1();
}
/**
*产品等级结构B的工厂方法
*/
publicProductBfactoryB(){
returnnewProductB1();
}
}
代码清单3:
具体工厂类ConcreteCreator2的源代码
packagecom.javapatterns.abstractfactory;
publicclassConcreteCreator2implementsCreator{
/**
*产品等级结构A的工厂方法
*/
publicProductAfactoryA(){
returnnewProductA1();
}
/**
*产品等级结构B的工厂方法
*/
publicProductBfactoryB(){
returnnewProductB1();
}
}
代码清单4:
具体产品类ProductA的源代码
packagecom.javapatterns.abstractfactory;
publicinterfaceProductA
{
}
代码清单5:
具体产品类ProductA1的源代码
packagecom.javapatterns.abstractfactory;
publicclassProductA1implementsProductA{
publicProductA1(){}
}
代码清单6:
具体产品类ProductA2的源代码
packagecom.javapatterns.abstractfactory;
publicclassProductA2implementsProductA{
publicProductA2(){}
}
代码清单7:
抽象产品角色ProductB的源代码
packagecom.javapatterns.abstractfactory;
publicinterfaceProductB{
}
代码清单8:
具体产品类ProductB1的源代码
packagecom.javapatterns.abstractfactory;
publicclassProductB1implementsProductB{
/***构造子*/
publicProductB1(){}
}
代码清单9:
具体产品类ProductB2的源代码
packagecom.javapatterns.abstractfactory;
publicclassProductB2implementsProductB{
/***构造子*/
publicProductB2(){}
}
工厂模式的相关应用:
★spring中的大量使用工厂模式。
★在SAX2库中,XMLReaderFactory类使用了简单工厂模式,用来创建产品类XMLReader的实例。
★用工具类java.text.DateFormat或其子类来格式化一个本地日期或者时间
★Java集合是Java1.2版提出来的。
多个对象聚在一起形成的总体称之为集合(Aggregate),集合对象是能够包容一组对象的容器对象。
所有的Java集合都实现java.util.Collection接口,这个接口规定所有的Java聚集必须提供一个iterator()方法,返还一个Iterator类型的对象一个具体的Java聚集对象会通过这个iterator()方法接口返还一个具体的Iterator类。
可以看出,这个iterator()方法就是一个工厂方法。
★在微软公司所提倡的COM(ComponentObjectModel)技术架构中,工厂方法模式起着关键的作用。
★在EJB技术架构中,工厂方法模式也起着关键的作用
★JMS(JavaMessagingService)技术架构中的工厂方法模式
2,单例(Singleton)模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
这个类称为单例类。
单例模式有以下三个的特点:
★单例类只可有一个实例。
★单例类必须自己创建自己这惟一的实例。
★单例类必须给所有其他对象提供这一实例。
注意:
虽然单例模式中的单例类被限定只能有一个实例,但是单例模式和单例类可以很容易被推广到任意且有限多个实例的情况,这时候称它为多例模式(MultitonPattern)和多例类(MultitonClass),
一个例子:
Windows回收站
在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且
回收站自行提供自己的实例。
因此,回收站是单例模式的应用。
单列模式的实现主要有两种:
饿汉式单例类和懒汉式单例类
1)饿汉式单例类
代码清单1:
饿汉式单例类
publicclassEagerSingleton{
privatestaticfinalEagerSingletonm_instance=newEagerSingleton();
/***私有的默认构造子*/
privateEagerSingleton(){}
/***静态工厂方法*/
publicstaticEagerSingletongetInstance(){
returnm_instance;
}
}
读者可以看出,在这个类被加载时,静态变量m_instance会被初始化,此时类的私有
构造子会被调用。
这时候,单例类的惟一实例就被创建出来了。
Java语言中单例类的一个最重要的特点是类的构造子是私有的,从而避免外界利用构
造子直接创建出任意多的实例。
值得指出的是,由于构造子是私有的,因此,此类不能被
继承。
2)懒汉式单例类。
与饿汉式单例类相同之处是,类的构造子是私有的。
与饿汉式单例类不同的是,懒汉
式单例类在第一次被引用时将自己实例化。
如果加载器是静态的,那么在懒汉式单例类被
加载时不会将自己实例化
代码清单2:
懒汉式单例类
packagecom.javapatterns.singleton.demos;
publicclassLazySingleton{
privatestaticLazySingletonm_instance=null;加载时并不创建对象,而是在需要的时候在创建
/**
*私有的默认构造子,保证外界无法直接实例化
*/
privateLazySingleton(){}
/***静态工厂方法,返还此类的惟一实例*/
synchronizedpublicstaticLazySingleton
getInstance(){
if(m_instance==null)
{m_instance=newLazySingleton();
}
returnm_instance;
}
}
读者可能会注意到,在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化,
以处理多线程环境。
有些设计师在这里建议使用所谓的“双重检查成例”。
必须指出的是,
“双重检查成例”不可以在Java语言中使用。
3)登记式单例类
登记式单例类是GoF为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的
这样做的缺点
由于子类必须允许父类以构造子调用产生实例,因此,它的构造子必须是公开的。
这样一来,就等于允许了以这样方式产生实例而不在父类的登记中。
这是登记式单例类的一个缺点。
GoF曾指出,由于父类的实例必须存在才可能有子类的实例,这在有些情况下是一个
浪费。
这是登记式单例类的另一个缺点。
3,多例模式
所谓的多例模式(MultitonPattern),实际上就是单例模式的自然推广。
作为对象的创
建模式,多例模式或多例类有以下的特点:
(1)多例类可有多个实例。
(2)多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
1)有上限多例模式。
一个实例数目有上限的多例类已经把实例的上限当做逻辑的一部分,并建造到了多例
类的内部,这种多例模式叫做有上限多例模式。
比如每一麻将牌局都需要两个色子,因此色子就应当是双态类。
这里就以这个系统为
例,说明多例模式的结构。
色子的类图如下所示。
下面就是多例类Die(色子)的源代码。
代码清单3:
多例类的源代码
packagecom.javapatterns.multilingual.dice;
importjava.util.Random;
importjava.util.Date;
publicclassDie{
privatestaticDiedie1=newDie();
privatestaticDiedie2=newDie();
/**
*私有的构造子保证外界无法
*直接将此类实例化
*/
privateDie(){}
/***工厂方法*/
publicstaticDiegetInstance(intwhichOne){
if(whichOne==1){
returndie1;
}
else{
returndie2;
}
}/***掷色子,返还一个在1~6之间的*随机数*/
publicsynchronizedintdice(){
Dated=newDate();
Randomr=newRandom(d.getTime());
intvalue=r.nextInt();
value=Math.abs(value);
value=value%6;
value+=1;
returnvalue;
}
}代码清单4:
客户端的源代码
packagecom.javapatterns.multilingual.dice;
publicclassClient{
privatestaticDiedie1,die2;
publicstaticvoidmain(String[]args){
die1=Die.getInstance
(1);
die2=Die.getInstance
(2);
die1.dice();
die2.dice();
}
}
2)无上限多例模式,由于没有上限的多例类对实例的数目是没有限制的,因此,虽然这种多例模式是单例模式的推广,但是这种多例类并不一定能够回到单例类。
应用:
序列键生成器与单例及多例模式
4,原始模式,通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。
这就是原始模型模式的用意。
Java语言的构件模型直接支持原始模型模式。
所有的JavaBean都继承自java.lang.Object,而Object类提供一个clone()方法,可以将一个JavaBean对象复制一份;但是这个JavaBean必须实现一个标示接口Cloneable表明这个JavaBean支持复制。
如果一个对象没有实现这个接口而调用clone()方法,Java编译器会抛出CloneNotSupportedException异常。
5建造模式,建造模式的定义为:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
可以将建造模式的精髓概括为:
将构造复杂对象的过程和对象的部件解耦。
这是对降低耦合、提高可复用性精神的一种贯彻。
其实这种精神贯彻在GOF几乎所有的设计模式中。
2)各类的说明如下:
i)抽象建造者(Builder)角色:
给出一个抽象接口,以规范产品对象的各个组成成分的构造;
ii)具体建造者(ConcretBuilder)角色:
它在应用程序的调用下创建产品的实例。
完成任务为;
a) 实现抽象建造者Builder接口,给出一步步完成创建产品实例的操作;
b) 在创建完成后,提供产品的实例。
iii)导演者(Director角色):
调用具体建造者角色以创建产品对象;
iv)产品(Product)角色:
建造中的复杂对象。
一般情况下,一个系统不止一个产品类。
Java中的应用:
javamail中使用建造者模式
6,适配器模式
目的:
将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器的两种模式:
类的适配器模式和对象的适配器模式
1)类的适配器模式,类的适配器模式把适配的类的API转换成目标类的API。
目标(Target)角色:
这就是所期待得到的接口。
源(Adaptee)角色:
现有需要适配的接口。
适配器(Adapter)角色:
适配器类是本模式的核心。
适配器把源接口转换成目标接口。
显然这一角色不可以是接口,而必须是具体类。
/***定义Client使用的与特定领域相关的接口 */
publicinterfaceTarget{
voidsampleOperation1();
voidsampleOperation2();
}
/***定义一个已经存在的接口,这个接口需要适配*/
publicclassAdaptee{
publicvoidsampleOperation1(){
//......
}
}
/***对Adaptee与Target接口进行适配*/
publicclassAdapterextendsAdapteeimplementsTarget{
publicvoidsampleOperation2(){
//......
}
}
2)对象的适配器,与类的适配器模式一样,对象适配器模式把适配的类的API
转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
示意代码如下:
/** *定义Client使用的与特定领域相关的接口*/
publicinterfaceTarget{
voidsampleOperation1();
voidsampleOperation2();
}
/** *定义一个已经存在的接口,这个接口需要适配*/
publicclassAdaptee{
publicvoidsampleOperation1(){
//......
}
}
/** *对Adaptee与Target接口进行适配 */
publicclassAdapterimplementsTarget{
privateAdapteeadaptee;
publicAdapter(Adapteeadaptee){
super();
this.adaptee=adaptee;
}
publicvoidsampleOperation1(){
adaptee.sampleOperation1();
}
publicvoidsampleOpera
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 模式
![提示](https://static.bdocx.com/images/bang_tan.gif)