版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java设计模式
i.i创建型模式
AbstractFactory(抽象工厂)
FactoryMethod(工厂方法)
Singleton(单态模式)
Builder(建造者模式)
Prototype(原型模式)
1.2结构型模式
Adapter(适配器模式)
Bridge(桥接模式)
Composite(组合模式)
Decorator(装配模式)
Facade(外观模式)
Flyweight(享元模式)
Proxy(代理模式)
1.3行为型模式
ChainofResponsibility(责任链模式)
Command(命令模式)
Interpreter(解释器模式)
Iterator(迭代器模式)
Mediator(中介者模式)
Memento(备忘录模式)
Observer(观察者模式)
State(状态模式)
Strategy(策略模式)
TemplateMethod(模板方法)
Visitor(访问者模式)
ToneyChen的总结
Singleton设计模式
Singleton单类模式是最简单的设计模式,它的主要作用是保证在程序运行生命
周期中,使用了单类模式的类只能有一个实例对象存在。单类模式实现了类似C
语言中全局变量的功能,单类模式常用于注册/查找的服务。
单类模式有两种实现方式:饱汉模式和饿汉模式,如下:
饱汉单类模式例子代码:
[java]viewplaincopy
1.publicclassSingletonl{
2.〃饱汉模式,声明时就创建实例对象
3.publicstaticfinalSingletonlinstance=newSingletonl();
4.〃单类模式的构造方法必须为private,以避免通过构造方法创建对象实例,
5.〃并且必须显示声明构造方法,以防止使用默认构造方法
6.privateSingletonl(){}
7.〃单类模式必须对外提供获取实例对象的方法
8.publicstaticSingletonlgelnstance(){
9.returninstance;
10.}
11.}
饿汉单类模式即延迟初始化单类方式,例子代码:
[java]viewplaincopy
1.publicclassSingleton2{
2.〃饿汉模式,声明时不创建实例对象
3.publicstaticSingleton2instance;
4.〃单类模式的构造方法必须为private,以避免通过构造方法创建对象实例,
5.〃并且必须显示声明构造方法,以防止使用默认构造方法
6.privateSingleton2(){}
7.〃单类模式必须对外提供获取实例对象的方法,延迟初始化的单类模式必须使用
synchronized同步关键字,否则多线程情况下很容易产生多个实例对象
8.publicstaticsynchronizedSingleton2gelnstance(){
9.〃延迟初始化,只有当第一次使用时才创建对象实例
10.if(instance==null){
11.returnnewSingleton2();
12.)
13.returninstance;
14.}
15.}
一般认为饱汉模式要比饿汉模式更加安全。
上面两种Singleton单类设计模式的实现方式都隐藏有如下的问题:
(1).虽然构造方式的访问修饰符为private,即除了自身以外其他任何类都无法
调用,但是通过反射机制的setAccessiable(true)方法可以访问私有方法和属
性。因此Singleton单类模式必须考虑这种例外情况。
⑵.对象序列化之后再反序列化时会生成新的对象,因此当Singleton单类模式
类实现序列化接口时,必须显式声明所有的字段为tranisento
在JDK1.5之后引入了Enum枚举,因此在JDK1.5之后Singleton单类模式又有
了第三种实现方式,也是最好的实现方式,例子如下:
[java]viewplaincopy
1.publicenumSingleton3{
2.INSTANCE{
3.publicvoiddoSomething(){
4.……
5.)
6.);
7.publicSingleton3getlnstance(){
8.returnINSTANCE;
9.)
10.publicabstractvoiddoSomething();
11.}
Singleton单类模式中只有一个INSTANCE枚举元素,枚举可以保证真个程序生命周期中只有
一个实例对象存在,同时还避免了常规Singleton单类模式private构造方法被反射调用和序
列化问题。
注意:java中除了构造方法可以创建对象实例以外,还可以通过克隆方法
(clone()是Object中的protected方法)来创建对象,若单类对象直接继承自
Object对象,则如果没有提供具体clone方法实现,则当调用克隆方法创建对
象时,会抛出运行时的异常CloneNotSupportedExceptiono
若单类类继承了实现克隆方法的类,则在单类类中必须覆盖父类的克隆方法,显
式抛出异常CloneNotSupportedExceptiono
另外,实现了单类模式的类不能再有派生子类,因为构造方式是私有的,子类无
法调用父类构造方法,因此达到了Final的效果。
Proxy设计模式
Proxy代理设计模式是一种控制对象访问的设计模式,类似于网络代理,网络代
理机制如下图:
客户端代理服务器目标资源
Proxy代理设计模式机制如下:
客户端程序代理程序目标程序
客户端程序通过代理程序来访问真正的目标程序,代理程序对外隐藏了目标程
序。普通代理设计模式例子代码如下:
[java]viewplaincopy
1.interfaceProxyBase{
2.publicvoidf();
3.publicvoidg();
4.publicvoidh();
5.)
6.〃代理程序
7.classProxyimplementProxyBase{
8.privateProxyBaseimplementation;
9.publicProxy(){
10.〃目标程序
11.implementation=newProxylmplementation();
12.)
13.publicvoidf(){
14.implementation.f();
15.}
16.publicvoidg(){
17.implementation.g();
18.}
19.publicvoidh(){
20.implementation.h();
21.)
22.}
23.〃目标程序
24.classProxyimplementationimplementsProxyBase{
25.publicvoidf(){
26.System.out.println(//Proxylmplementation.f(),,);
27.}
28.publicvoidg(){
29.System.out.println(zzProxylmplementation.g(),,);
30.}
31.publicvoidh(){
32.System.out.println(//Proxylmplementation.h(),,);
33.}
34.}
35.〃客户端程序调用代理
36.publicclassProxyDemo{
37.publicstaticvoidmain(String[]args){
38.〃客户端调用代理程序
39.Proxyp=newProxy();
40.p.f();
41.p.g();
42.p.h();
43.}
44.}
从JDK1.3以后,java引入动态代理机制,java的动态代理只能针对接口进行动
态代理,即要实现动态代理的类必须实现接口,CGLIB提供了针对类的动态代理
功能。JDK动态代理的例子如下:
[java]viewplaincopy
1.〃代理接口
2.interfaceFoo{
3.publicvoidf(Strings);
4.publicvoidg(inti);
5.publicvoidh(inti,Strings);
6.}
7.〃接口实现类,即被代理类
8.classFoolmplimplementsFoo{
9.publicvoidf(Strings){
10.System.out.printlnCTooImpl.fO,s="+s);
11.}
12.publicvoidg(inti){
13.System.out.printlnC'FooImpl,gO,i=",+i);
14.)
15.publicvoidh(inti,Strings){
16.System.out.printlnC'FooImpl.hO,\=f,+i+s="+s);
17.)
18.)
19.〃动态代理处理类
20.classProxyHandlerimplementslnvocationHandler{
21.〃代理实现类
22.privateObjectdelegate;
23.publicProxyHandler(Objectobj){
24.delegate=obj;
25.)
26.publicObjectinvoke(Objectproxy,Methodmethod,Object[]args){
27.System.out.println(zzBeforemothod:"+method);
28.method.invoke(this.delegate,args);
29.System.out.printlnf^Aftermothod:〃+method);
30.returnnull;
31.)
32.}
33.publicclassDynamicProxyDemo{
34.publicstaticvoidmain(String[]args){
35.Foofoo=newFoolmpl();
36.ProxyHandlerhandler=newProxyHandler(foo);
37.〃产生动态代理
38.Fooproxy=(Foo)Proxy.newProxylnstance(Foo.class.getClassLoader(),newClass[]{Foo.
class},handler);
39.proxy.f("f〃);
40.proxy.g(l);
41.proxy.h("h",2);
42.}
43.)
动态代理和普通的代理模式的区别:动态代理中的代理类是由
java.lang,reflect.Proxy类在运行期时根据接口定义,采用Java反射功能动
态生成的。和java.lang,reflect.InvocationHandler结合,可以加强现有类的
方法实现。动态带来自定义Handler实现InvocationHandler接口,自定义
Handler实例化时,将代理的实现类传入自定义Handler对象中。自定义Handler
需要实现invoke方法,该方法可以使用Java反射调用实现类的实现的方法,同
时当然可以实现其他功能,例如在调用实现类方法前后加入Log,实现安全认证
等。而Proxy类根据Handler和需要代理的接口动态生成一个接口实现类的对象。
当用户调用这个动态生成的实现类时,实际上是调用了自定义Handler的
invoke方法。
State设计模式
State状态设计模式类似于Switch多路分支功能的开关,State状态模式机制如
下:
State状态设计模式用于改变对象的行为,在代理的生命周期里,随着状态变化
从一个目标实现程序切换到另一个目标实现程序。
我们经常遇到如下的程序代码:
[java]viewplaincopy
1.publicclassCreature{
2.privateBooleanisFrog=true;〃标识
3.publicvoidgreet(){
4.if(isForg){
5.System.out.println(//Ribbet!,,);
6.}else{
7.System.out.println(/zDarling!,/);
8.)
9.)
10.〃转换标识
11.publicvoidkiss(){
12.isForg=false;
13.}
14.publicstaticvoidmain(String[]args){
15.Creaturecreature=newCreature();
16.creature.greet();
17.creature.kiss();
18.creature.greet();
19.}
20.}
上面例子代码中greet。方法在执行具体操作之前必须要判断一下标识,代码显得笨拙繁
琐,使用简单State状态模式改写上面代码如下:
[java]viewplaincopy
1.publicclassCreature{
2.〃状态接口
3.privateinterfaceState{
4.Stringresponse();
5.)
6.privateclassForgimplementsState{
7.publicStringresponse(){
8.return"Ribbet!〃;
9.)
10.}
11.privateclassPrinceimplementsState{
12.publicStringresponse(){
13.return"Darling!”;
14.}
15.}
16.privateStatestate=newForg();
17.publicvoidgreet(){
18.System.out.println(state.response);
19.}
20.publicvoidkiss(){
21.state=newPrince();
22.}
23.publicstaticvoidmain(String[]args){
24.Creaturecreature=newCreature();
25.creature.greet();
26.creature.kiss();
27.creature.greet();
28.}
29.}
State状态设计模式中,状态自动切换并传播,不需要再改动标识,代码显得非
常优雅。
State状态设计模式一个基本框架如下:
[java]viewplaincopy
1.〃状态接口
2.interfaceState{
3.voidoperationl();
4.voidoperation2();
5.voidoperation3();
6.}
7.〃状态实现类1
8.classimplementation!implementsState{
9.publicvoidoperationl(){
10.System.out.println(//lmplementationl.operationl(),,);
11.}
12.publicvoidoperation2(){
13.System.out.println(//lmplementationl.operation2(),,);
14.}
15.publicvoidoperation3(){
16.System.out.println(//lmplementationl.operation3(),,);
17.}
18.}
19.〃状态实现类2
20.classimplementation2implementsState{
21.publicvoidoperationl(){
22.System.out.println(//lmplementation2.operationl(),,);
23.}
24.publicvoidoperation2(){
25.System.out.println(z/lmplementation2.operation2(),,);
26.}
27.publicvoidoperation3(){
28.System.out.println(//lmplementation2.operation3(),,);
29.}
30.}
31.〃服务提供者
32.classServiceProvider{
33.privateStatestate;
34.publicServiceProvider(Statestate){
35.this.state=state;
36.)
37.〃状态更改
38.publicvoidchangeState(StatenewState){
39.state=newState;
40.)
41.publicvoidservicel(){
42.//……
43.state.operationl();
44.//……
45.state.operation3();
46.}
47.publicvoidservice2(){
48.//……
49.state.operationl();
50.//……
51.state.operation2();
52.}
53.publicvoidservice3(){
54.//……
55.state.operation3();
56.//……
57.state.operation2();
58.}
59.}
60.publicclassStateDemo{
61.privateServiceProvidersp=newServiceProvider(newlmplementationl());
62.privatevoidrun(ServiceProvidersp){
63.sp.servicel();
64.sp.service2();
65.sp.service3();
66.}
67.publicstaticvoidmain(String[]args){
68.StateDemodemo=newStateDemo();
69.demo.run(sp);
70.sp.changeState(newImplementation2());
71.demo.run(sp);
72.)
73.}
State状态模式和Proxy代理模式都为客户端程序提供了一个目标程序代理,真
正的目标程序被代理所隐藏,当客户端程序调用目标程序时,首先将调用请求发
送给代理,代理才真正调用目标程序,但是Proxy代理模式和State状态模式有
如下区别:
(D.Proxy代理模式中被调用的目标程序只有一个,而State状态模式中被调
用的目标程序有多个。
⑵.Proxy代理模式的目的是控制客户端对目标程序的访问,而State状态模式
是为了根据条件动态改变目标程序。
Itrator设计模式
Iterator迭代器模式,提供一种统一的方法访问-一个容器(container)对象中
各个元素,而又不需暴露该对象的内部细节,迭代器模式是为容器而设计。
程序对容器对象的访问必然涉及到遍历算法,不同的容器遍历算法是不同的,
List,Stack和Set等等常用容器遍历元素的算法各不相同。解决容器遍历算
法差异有两种方案:第一,可以将遍历方法塞到容器对象中去,容器承受了过多
的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而且
还要提供遍历自身的接口;第二,根本不提供容器遍历算法,让容器使用者自己
去实现。该方法虽然是省事,却又将容器的内部细节暴露无遗。迭代器模式的
出现,很好的解决了上面两种情况的弊端,不但将遍历容器的算法从不同集合
容器类中抽象出来,同时又对外隐藏了容器的具体实现细节。
迭代器模式由以下角色组成:
1)迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
2)具体迭代器角色(ConcreteIterator):具体迭代器角色要实现迭代器接口,
并要记录遍历中的当前位置。
3)容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。
4)具体容器角色(ConcreteContainer):具体容器角色实现创建具体迭代器
角色的接口——这个具体迭代器角色于该容器的结构相关。
Java集合框架中迭代设计模式的应用:
[java]viewplaincopy
1.〃迭代器,该接口提供了迭代遍历的通用方法
2.publicinterfaceIterator{
3.booleanhasNext();
4.Objectnext();
5.voidremove();
6.)
7.〃容器迭代化接口,凡是实现此接口的集合容器距可以生成相应的迭代器
8.publicinterfacelterable<T>{
9.〃产生迭代器,将容器对象转换为迭代器对象
10.lterator<T>interator();
11.}
12.〃java集合框架的根接口,该接口继承了容器迭代化接口,因此java中的集合都可
以被迭代
13.publicinterfaceCollection<E>extendslterable<E>
自定义迭代器,以ArrayList为自定义迭代容器的底层数据结构,实现自定义迭
代器的代码如下:
[java]viewplaincopy
1.publicclassMylteratorimplementsIterable{
2.〃存放数据的集合
3.privateArrayListlist;
4.〃负责创建具体迭代器角色的工厂方法
5.publicIteratoriterator(){
6.returnnewItr(list);
7.)
8.〃作为内部类的具体迭代器角色
9.privateclassItrimplementsIterator{
10.ArrayListmyList;
11.intposition=0;
12.publicltr(ArrayListlist){
13.this.myList=list;
14.}
15.publicObjectnext(){
16.Objectobj=myList.get(position);
17.position++;
18.returnobj;
19.}
20.publicbooleanhasNext(){
21.if(position>=myList.size()){
22.returnfalse;
23.}else{
24.returntrue;
25.)
26.}
27.〃不支持remove操作
28.publicvoidremove(){
29.thrownewUnsupportedOperationException(
30."AlternatingMylteratordoesnotsupportremove()");
31.}
32.}
33.}
使用时,Mylterator对象直接调用iterator()方法就可以将自定义容器对象转
换为迭代器对象。
Iterator模式的优点:
(1).实现功能分离,简化容器接口。让容器只实现本身的基本功能,把迭代功能
委让给外部类实现,符合类的设计原则。
(2).隐藏容器的实现细节。
(3).为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调
用者不必关注迭代器的实现细节。
(4).可以为容器或其子容器实现不同的迭代方法或多个迭代方法o
Strategy设计模式
Strategy策略设计模式主要是定义一系列的算法,把这些算法封装成单独的类,
在运行时动态选择需要的算法,策略模式机制如下:
策略模式例子如下:
[java]viewplaincopy
1.〃文本替换策略
2.abstractclassTextstrategy{
3.protectedStringtext;
4.
5.publicTextStrategyfStringtext){
6.this.text=text;
7.}
8.publicabstractStringreplace();
9.)
10.〃替换算法1:将文本中"@r@n"替换为"@n"
11.classStrategyOneextendsTextStrategy{
12.publicStrategyOne(Stringtext){
13.super(text);
14.}
15.publicStringreplace(){
16.System.out.println(/zStrategyOne:,,);
17.Stringresult=text.replaceAII("@r©n","@n"));
18.returnresult;
19.}
20.}
21.〃替换算法2:将文本中"@n"替换为"@r@n"
22.classStrategyTwoextendsTextstrategy{
23.publicStrategyTwo(Stringtext){
24.super(text);
25.}
26.publicStringreplace(){
27.System.out.println(//StrategyTwo:,9;
28.Stringresult=text.replaceAII(〃@n”,“@r@n”));
29.returnresult;
30.}
31.}
32.publicclassTextCharChange{
33.publicstaticvoidreplace(TextStrategystrategy){
34.strategy.replace();
35.}
36.publicstaticvoidmain(String[]args){
37.StringtestTextl="Thisisatesttext!!@nOh!LineReturn!!@n";
38.StringtestText2=Thisisatesttext!!@r@nOh!LineReturn@r@n";
39.TextCharChange.replace(newStrategyOne(testText2));
40.TextCharChange.replace(newStrategyTwo(testTextl));
41.}
42.}
State状态模式和Strategy策略模式非常类似,但是有如下区别:
(1).State状态模式重点在于设定状态变化,根据状态,返回相应的响应。
⑵.Strategy策略模式重点在于根据需求直接采用设定的策略,即根据场景选
择合适的处理算法,而不需要改变状态。
Factory设计模式
Factory工厂设计模式为创建对象提供了一种抽象,而对使用者屏蔽了对象创建
的具体细节过程,工厂模式有三种:简单工厂模式,抽象工厂模式和工厂方法模
式。
(1).简单工厂模式:
又叫静态工厂模式,简单工厂只包括一个抽象产品类(该类可以是接口,也可以
是具体的类),所有需要的产品类都是该抽象产品类的子类。简单工厂模式中工
厂为具体产品工厂,产品为抽象产品,由工厂实例创建产品实例:
«interTace»
Product
।____________________________________________________
creates
一个生成圆形和矩形的图形工厂,例子如下:
[java]viewplaincopy
1.〃图形接口
2.interfaceShape(){
3.publicvoiddraw();
4.)
5.〃圆形
6.classCircleimplementsShape{
7.publicvoiddraw(){
8.System.out.println(zzCircleisdrawing");
9.)
10.}
IL〃矩形
12.classRectangleimplementsShape{
13.publicvoiddraw(){
14.System.out.println("Rectangleisdrawing");
15.)
16.}
17.〃图形工厂
18.classShapeFactory{
19.publicstaticShapecreateShape(Stringname)throwsInstantiationException,
20.HlegalAccessException,
21.ClassNotFoundException
22.{
23.〃使用java的反射机制来产生对象实例
24.return(Shape)class.forName(name),newlnstance();
25.}
26.}
27.publicclassShapeDemo{
28.publicstaticvoiddraw(Shapeshape){
29.shape.draw();
30.}
31.publicstaticvoidmain(String[]args){
32.draw(ShapeFactory.createShape(zzCircle,/));
33.draw(ShapeFactory.createShape(//Rectangle,/));
34.}
35.}
图形工厂负责具体图形的对象实例化工作,图形使用者使用时不需要关心图形对
象的具体产生过程。
(2).抽象工厂模式:
抽象工厂模式中可以包括多个抽象产品类,每个抽象产品类可以产生出多个具体
产品类,一个抽象工厂用于定义所需产品的组合形式,抽象工厂派生具体工厂类,
这些具体工厂类就是简单工厂模式中的工厂类,具体工厂类负责具体产品实例的
创建:
Client
«interface»«interface»
AbstractFactoryProductA
+productAOProductA+operationW-void
+productBQ-ProductB+operation20:void
F✓飞,
FactorylProductA1ProductA2
+productAO:ProductA+operationlO:void+operationlO:void
+productBQ:Products+operation?。:void+operation20:void
K
Factoiy2
+productAO:ProductA
+productBQ:Products«interface»
ProductB
+operationlO:void
+operation20:void
/\
ProductB1ProductB2
+operationlO:void+operationlO:void
+operation?。:void+operation?。:void
I
以软件皮肤为例,软件皮肤由样式style和颜色color组成,实现一套I0S风格
的软件皮肤,一套Android风格的软件皮肤,通过抽象工厂实现软件皮肤自由切
换例子如下:
[java]viewplaincopy
1〃软件皮肤类
2classSkin{
3privateSkinFactoryskinFactory;
4publicSkin(SkinFactoryfactory){
5setSkinFactory(factory);
6)
7publicvoidsetSkinFactory(SkinFactoryfactory){
8this.skinFactory=factory
9.)
10.publicvoidshowSkin(){
11.System.out.println("Style="+factory.getStyle().showStyle()+”,color="+factory,getCo
lor().showColor());
12.)
13.}
14.〃软件Style
15.interfaceStyle(){
16.publicvoidshowStyle();
17.}
18.//IOSstyle
19.classlOSStyleimplementsStyle{
20.publicvoidshowStyle(){
21.System.out.println(/zThisisIOSstyle");
22.}
23.}
24.//Androidstyle
25.classAndroidStyleimplementsStyle{
26.publicvoidshowStyle(){
27.System.out.println(z/ThisisAndroidstyle");
28.}
29.}
30.〃软件Color
31.interfaceColor(){
32.publicvoidshowColor();
33.}
34.//IOScolor
35.classlOSColorimplementsColor{
36.publicvoidshowColor(){
37.System.out.println(/zThisisIOScolor");
38.}
39.}
40.//Androidcolor
41.classAndroidColorimplementsColor{
42.publicvoidshowColor(){
43.System.out.println(/zThisisAndroidcolor");
44.}
45.)
46.〃抽象皮肤工厂
47.interfaceSkinFactory{
48.publicStylegetStyle();
49.publicColorgetColor();
50.}
51.//IOS皮肤工厂
52.classlOSSkinFactoryimplementsSkinFactory{
53.publicStylegetStyle(){
54.returnnewIOSStyle();
55.}
56.publicColorgetColor(){
57.returnnewIOSColor();
58.}
59.}
60.//Android皮肤工厂
61.classAndroidSkinFactoryimplementsSkinFactory{
62.publicStylegetStyle(){
63.returnnewAndroidStyle();
64.}
65.publicColorgetColor(){
66.returnnewAndroidColor();
67.}
68.}
69.publicclassSkinDemo{
70.publicstaticvoidmain(String[]args){
71.〃显示一套IOS皮肤
72.Skinskin=newSkin(newIOSSkinFactory());
73.skin.showSkin();
74.〃换一套Android的皮肤
75.skin.setSkinFactory(newAndroidSkinFactoryO);
76.skin.showSkin();
77.}
78.}
抽象工厂指定了产品组合形式,具体的工厂产生具体的产品,抽象工厂适用于多个产品相互
组合的情况。
(3).工厂方法模式:
工厂方法中也只包含一个抽象产品类,抽象产品类可以派生出多个具体产品类。
工厂方法定义一个用于创建产品的接口,让子类决定实例化哪一个类,使得类的
实例化延迟到子类。
^A
ConcreateProductA
ConcreateFactoryA
T
+operationlO:void
+ereate0:Product
+operation2Q:void
ConcreateProductB
ConcreateFactoryB
+operationlO:void
+ereate0:Product
+operation?。:void
工厂方法模式例子如下:
[java]viewplaincopy
1.〃汽车接口
2.interfaceICar{
3.publicvoidrun();
4.}
5.〃奔驰车
6.classBenzCarimplementsICar{
7.publicvoidrun(){
8.System.out.println(/zBenzcarrun");
9.}
10.}
n.〃宝马车
12.classBMWCarimplementsICar{
13.publicvoidrun(){
14.System.out.println(zzBMWcarrun?,);
15.)
16.}
17.〃抽象汽车工厂
18.abstractclassCarFactory{
19.publicabstractICarcreateCar();
20.}
21.〃奔驰车工厂
22.classBenzCarFactoryextendsCarFactory{
23.publicICarcreateCar(){
24.returnnewBenzCar();
25.}
26.}
27.〃宝马车工厂
28.classBMWCarFactoryextendsCarFactory{
29.publicICarcreateCar(){
30.returnnewBMWCar();
31.}
32.}
33.publicclassFactoryMethodDemo{
34.publicstaticvoidmain(String[]args){
35.CarFactoryfactory=newBenzCarFactory();
36.ICarcar=factory.createCar();
37.car.run();
38.factory=newBMWCarFactoryO;
39.car=factory.createCar();
40.car.run();
41.}
42.}
工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继
承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的
实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。工
厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。
三种工厂模式的区别:
简单工厂:用来生产同一等级结构中的任意产品,对于增加新的产品,无能为
力。
工厂方法:用来生产同一等级结构中的固定产品,支持增加任意产品。
抽象工厂:用来生产不同产品族(由不同产品组合成的一套产品)的全部产品,
对于增加新的产品,无能为力;支持增加产品族。
Prototype设计模式
Prototype原型设计模式是指用原型实例指定创建对象的种类,并且通过拷贝这
些原型来创建新的对象。Prototype原型模式允许一个对象再创建另外一个可定
制的对象,根本无需知道任何关于对象创建的细节。
Prototype模式例子如下:
[java]viewplaincopy
1.〃抽象原型类
2.abstractclassShapeimplementsColneable{
3.StringshapeName;
4.publicStringgetShapeName(){
5.retunshapeName;
6.)
7.publicvoidsetShapeName(StringshapeName){
8.this.shapeName=shapeName;
9.)
10.〃实现了Colneable接口的类,可以使用clone。方法复制对象
11.publicObjectclone(){
12.try{
13.returnsuper.clone();
14.}catch(CloneNotSupportedExceptione){
15.System.eirprintln(〃此对象不支持复制〃);
16.}
17.returnnull;
18.}
19.}
20.〃具体原型类
21.pubicclassCircleextendsShape{
22.publicCircle(){
23.setShapeName(/zCircleshape");
24.}
25.publicstaticvoidmain(String[]args){
26.Shapeshape=newCircle();
27.System.out.println(shape.getShapeName());
28.〃通过clone。方法获得一个对象拷贝
29.Shapeshape2=(Shape)shape.clone();
30.System.out.println(shape2.getShapeName());
31.}
32.}
clone。方法是在Object中定义的,而且是protected的,只有实现了Cloneable
接口的类才可以在其实例上调用clone。方法,否则会抛出
CloneNotSupportException0
为了获取对象的一份拷贝,我们可以利用Object类的clone。方法,也可以实
现Cloneable接口,覆盖基类的clone()方法,在clone。方法中,调用
super,clone()。
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:
[java]viewplaincopy
1.packagejava.lang;
2.pubilcinterfaceCloneable{
3.)
更多有关java拷贝方面的内容请参考
http://blog.csdn.net/chjttony/article/details/7477346
克隆只是实现Prototype原型模式的一种方法,也可以直接通过new对象的方式
创建原型实例,二者区别在于:
(1).通过new方式创建的原型和现存的实例对象没有任何联系。
(2).通过克隆方法创建的原型,虽然也是创建新对象,但是将原型实例对象的数
据复制到了新的对象中,相当于使用被克隆对象的数据作为克隆对象的初始数
据。
Prototype原型设计模式和Singleton单类设计模式是相对的,单类模式中,在
整个程序生命周期里,单类模式类的实例对象只有一个。而Prototype原型设计
模式则正好相反,每次都返回的是原型类的不同实例对象。
Java中的深拷贝和浅拷贝
1.浅拷贝与深拷贝概念
⑴浅拷贝(浅克隆)
浅拷贝又叫浅复制,将对象中的所有字段复制到新的对象(副本)中。其中,
值类型字段(java中8中原始类型)的值被复制到副本中后,在副本中的修改不
会影响到源对象对应的值。而引用类型的字段被复制到副本中的还是引用类型的
引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象
本身。
浅拷贝简单归纳就是只复制一个对象,对象内部存在指向其他对象,数组或引用
则不复制。
⑵深拷贝(深克隆)
将对象中的所有字段复制到新的对象中。不过,无论是对象的值类型字段,还
是引用类型字段,都会被重新创建并赋值,对于副本的修改,不会影响到源对象
本身。
深拷贝简单归纳就是对象内部引用的对象均复制。
2.Java中的clone()方法
(1)clone。方法将对象复制了一份并返回给调用者。一般而言,clone。方法满
足下面规范:
①对任何的对象x,都有x.clone。!=x;〃克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()==x.getClass();〃克隆对象与
原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x);应该成立。
(2)Java中对象的克隆
clone()方法是在Object中定义的,而且是protected的,只有实现了Cloneable
接口的类才可以在其实例上调用clone。方法,否则会抛出
CloneNotSupportException0
为了获取对象的一份拷贝,我们可以利用Object类的clone。方法,也可以实
现Cloneable接口,覆盖基类的clone()方法,在clone。方法中,调用
super,clone()。
Cloneable接口是一个标记接口,也就是没有任何内容,定义如下:
packagejava,lang;
publicinterfaceCloneable{
)
例子代码如下:
[java]viewplaincopy
1.classStudentimplementsCloneable
2.(
3.Stringname;
4.intage;
5.Student(Stringname,intage){
6.=name;
7.this.age=age;
8.)
9.publicObjectclone(){
10.Objecto=null;
11.try{
12.//Object中的clone。识别出你要复制的是哪一个对象
13.o=(Student)super.clone();
14.}catch(CloneNotSupportedExceptione){
15.System.out.println(e.toString());
16.}
17.returno;
18.}
19.}
20.publicstaticvoidmain(String[]args){
21.Studentsl=newStudent("zhangsan",18);
22.Students2=(Student)sl.clone();
23.="lisi";
24.s2.age=20;
25.System.out.println("name="++","+"age="+sl.age);//>g^^^2后,不影响学生
1的值。
26.}
说明:
①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用
super,clone()呢?
在运行时刻,Object中的clone。识别出你要复制的是哪一个对象,然后为此对
象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空
间中。
②继承自java.lang.Object类的clone()方法是浅复制。以下代码可以证明:
[java]viewplaincopy
1.//Professor没有实现Cloneable接口,默认使用java.lang.Object类的clone。方法
2.classProfessor{
3.Stringname;
4.intage;
5.Professor(Stringname,intage){
6.=name;
7.this.age=age;
8.}
9.)
10."Student实现了Cloneable接口
11.classStudentimplementsCloneable{
12.Stringname;〃常量对象。
13.intage;
14.Professorp;
15.Student(Stringname,intage,Professorp){
16.=name;
17.this.age=age;
18.this.p=p;
19.}
20.publicObjectclone(){
21.Studento=null;
22.try{
23.o=(Student)super.clone();
24.}catch(CloneNotSupportedExceptione){
25.System.out.println(e.toString());
26.}
27.〃使用Object类的clone。方法
28.o.p=(Professo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 媒体娱乐公司估值考量要点
- 2024.0913推文-一步法elisa新品解读
- 2024高中地理第五章区际联系与区域协调发展第2节产业转移-以东亚为例精练含解析新人教必修3
- 2024高中生物专题4酶的研究与应用课题2探讨加酶洗衣粉的洗涤效果课堂演练含解析新人教版选修1
- 2024高考地理一轮复习第十五单元区域生态环境建设练习含解析
- 2024高考化学一轮复习第八章水溶液中的离子平衡第三节盐类的水解学案新人教版
- 2024高考化学二轮复习选择题专项练四含解析
- 2024高考地理一轮复习特色篇六新颖等值线图练习含解析
- (4篇)2024年有关一年级英语培优补差的教学工作总结
- 二零二五年度茶山茶叶种植基地租赁合同范本5篇
- 2025年国新国际投资有限公司招聘笔试参考题库含答案解析
- 制造车间用洗地机安全操作规程
- 2025河南省建筑安全员-A证考试题库及答案
- 油气田智能优化设计-洞察分析
- 陕西2020-2024年中考英语五年真题汇编学生版-专题09 阅读七选五
- 砖混结构基础加固技术方案
- 多源数据融合平台建设方案
- 2023-2024学年上海市普陀区三年级(上)期末数学试卷
- 居家养老上门服务投标文件
- 浙江省宁波市鄞州区2024年七年级上学期期末数学试题【含答案】
- 小班班本课程《吃饭这件小事》
评论
0/150
提交评论