Java程序設計模式程序設計_第1頁
Java程序設計模式程序設計_第2頁
Java程序設計模式程序設計_第3頁
Java程序設計模式程序設計_第4頁
Java程序設計模式程序設計_第5頁
已閱讀5頁,還剩68頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Java設計模式

i.i創(chuàng)建型模式

AbstractFactory(抽象工廠)

FactoryMethod(工廠方法)

Singleton(單態(tài)模式)

Builder(建造者模式)

Prototype(原型模式)

1.2結構型模式

Adapter(適配器模式)

Bridge(橋接模式)

Composite(組合模式)

Decorator(裝配模式)

Facade(外觀模式)

Flyweight(享元模式)

Proxy(代理模式)

1.3行為型模式

ChainofResponsibility(責任鏈模式)

Command(命令模式)

Interpreter(解釋器模式)

Iterator(迭代器模式)

Mediator(中介者模式)

Memento(備忘錄模式)

Observer(觀察者模式)

State(狀態(tài)模式)

Strategy(策略模式)

TemplateMethod(模板方法)

Visitor(訪問者模式)

ToneyChen的總結

Singleton設計模式

Singleton單類模式是最簡單的設計模式,它的主要作用是保證在程序運行生命

周期中,使用了單類模式的類只能有一個實例對象存在。單類模式實現(xiàn)了類似C

語言中全局變量的功能,單類模式常用于注冊/查找的服務。

單類模式有兩種實現(xiàn)方式:飽漢模式和餓漢模式,如下:

飽漢單類模式例子代碼:

[java]viewplaincopy

1.publicclassSingletonl{

2.〃飽漢模式,聲明時就創(chuàng)建實例對象

3.publicstaticfinalSingletonlinstance=newSingletonl();

4.〃單類模式的構造方法必須為private,以避免通過構造方法創(chuàng)建對象實例,

5.〃并且必須顯示聲明構造方法,以防止使用默認構造方法

6.privateSingletonl(){}

7.〃單類模式必須對外提供獲取實例對象的方法

8.publicstaticSingletonlgelnstance(){

9.returninstance;

10.}

11.}

餓漢單類模式即延遲初始化單類方式,例子代碼:

[java]viewplaincopy

1.publicclassSingleton2{

2.〃餓漢模式,聲明時不創(chuàng)建實例對象

3.publicstaticSingleton2instance;

4.〃單類模式的構造方法必須為private,以避免通過構造方法創(chuàng)建對象實例,

5.〃并且必須顯示聲明構造方法,以防止使用默認構造方法

6.privateSingleton2(){}

7.〃單類模式必須對外提供獲取實例對象的方法,延遲初始化的單類模式必須使用

synchronized同步關鍵字,否則多線程情況下很容易產(chǎn)生多個實例對象

8.publicstaticsynchronizedSingleton2gelnstance(){

9.〃延遲初始化,只有當?shù)谝淮问褂脮r才創(chuàng)建對象實例

10.if(instance==null){

11.returnnewSingleton2();

12.)

13.returninstance;

14.}

15.}

一般認為飽漢模式要比餓漢模式更加安全。

上面兩種Singleton單類設計模式的實現(xiàn)方式都隱藏有如下的問題:

(1).雖然構造方式的訪問修飾符為private,即除了自身以外其他任何類都無法

調(diào)用,但是通過反射機制的setAccessiable(true)方法可以訪問私有方法和屬

性。因此Singleton單類模式必須考慮這種例外情況。

⑵.對象序列化之后再反序列化時會生成新的對象,因此當Singleton單類模式

類實現(xiàn)序列化接口時,必須顯式聲明所有的字段為tranisento

在JDK1.5之后引入了Enum枚舉,因此在JDK1.5之后Singleton單類模式又有

了第三種實現(xiàn)方式,也是最好的實現(xiàn)方式,例子如下:

[java]viewplaincopy

1.publicenumSingleton3{

2.INSTANCE{

3.publicvoiddoSomething(){

4.……

5.)

6.);

7.publicSingleton3getlnstance(){

8.returnINSTANCE;

9.)

10.publicabstractvoiddoSomething();

11.}

Singleton單類模式中只有一個INSTANCE枚舉元素,枚舉可以保證真?zhèn)€程序生命周期中只有

一個實例對象存在,同時還避免了常規(guī)Singleton單類模式private構造方法被反射調(diào)用和序

列化問題。

注意:java中除了構造方法可以創(chuàng)建對象實例以外,還可以通過克隆方法

(clone()是Object中的protected方法)來創(chuàng)建對象,若單類對象直接繼承自

Object對象,則如果沒有提供具體clone方法實現(xiàn),則當調(diào)用克隆方法創(chuàng)建對

象時,會拋出運行時的異常CloneNotSupportedExceptiono

若單類類繼承了實現(xiàn)克隆方法的類,則在單類類中必須覆蓋父類的克隆方法,顯

式拋出異常CloneNotSupportedExceptiono

另外,實現(xiàn)了單類模式的類不能再有派生子類,因為構造方式是私有的,子類無

法調(diào)用父類構造方法,因此達到了Final的效果。

Proxy設計模式

Proxy代理設計模式是一種控制對象訪問的設計模式,類似于網(wǎng)絡代理,網(wǎng)絡代

理機制如下圖:

客戶端代理服務器目標資源

Proxy代理設計模式機制如下:

客戶端程序代理程序目標程序

客戶端程序通過代理程序來訪問真正的目標程序,代理程序?qū)ν怆[藏了目標程

序。普通代理設計模式例子代碼如下:

[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.〃客戶端程序調(diào)用代理

36.publicclassProxyDemo{

37.publicstaticvoidmain(String[]args){

38.〃客戶端調(diào)用代理程序

39.Proxyp=newProxy();

40.p.f();

41.p.g();

42.p.h();

43.}

44.}

從JDK1.3以后,java引入動態(tài)代理機制,java的動態(tài)代理只能針對接口進行動

態(tài)代理,即要實現(xiàn)動態(tài)代理的類必須實現(xiàn)接口,CGLIB提供了針對類的動態(tài)代理

功能。JDK動態(tài)代理的例子如下:

[java]viewplaincopy

1.〃代理接口

2.interfaceFoo{

3.publicvoidf(Strings);

4.publicvoidg(inti);

5.publicvoidh(inti,Strings);

6.}

7.〃接口實現(xiàn)類,即被代理類

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.〃動態(tài)代理處理類

20.classProxyHandlerimplementslnvocationHandler{

21.〃代理實現(xiàn)類

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.〃產(chǎn)生動態(tài)代理

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.)

動態(tài)代理和普通的代理模式的區(qū)別:動態(tài)代理中的代理類是由

java.lang,reflect.Proxy類在運行期時根據(jù)接口定義,采用Java反射功能動

態(tài)生成的。和java.lang,reflect.InvocationHandler結合,可以加強現(xiàn)有類的

方法實現(xiàn)。動態(tài)帶來自定義Handler實現(xiàn)InvocationHandler接口,自定義

Handler實例化時,將代理的實現(xiàn)類傳入自定義Handler對象中。自定義Handler

需要實現(xiàn)invoke方法,該方法可以使用Java反射調(diào)用實現(xiàn)類的實現(xiàn)的方法,同

時當然可以實現(xiàn)其他功能,例如在調(diào)用實現(xiàn)類方法前后加入Log,實現(xiàn)安全認證

等。而Proxy類根據(jù)Handler和需要代理的接口動態(tài)生成一個接口實現(xiàn)類的對象。

當用戶調(diào)用這個動態(tài)生成的實現(xiàn)類時,實際上是調(diào)用了自定義Handler的

invoke方法。

State設計模式

State狀態(tài)設計模式類似于Switch多路分支功能的開關,State狀態(tài)模式機制如

下:

State狀態(tài)設計模式用于改變對象的行為,在代理的生命周期里,隨著狀態(tài)變化

從一個目標實現(xiàn)程序切換到另一個目標實現(xiàn)程序。

我們經(jīng)常遇到如下的程序代碼:

[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.〃轉(zhuǎn)換標識

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。方法在執(zhí)行具體操作之前必須要判斷一下標識,代碼顯得笨拙繁

瑣,使用簡單State狀態(tài)模式改寫上面代碼如下:

[java]viewplaincopy

1.publicclassCreature{

2.〃狀態(tài)接口

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狀態(tài)設計模式中,狀態(tài)自動切換并傳播,不需要再改動標識,代碼顯得非

常優(yōu)雅。

State狀態(tài)設計模式一個基本框架如下:

[java]viewplaincopy

1.〃狀態(tài)接口

2.interfaceState{

3.voidoperationl();

4.voidoperation2();

5.voidoperation3();

6.}

7.〃狀態(tài)實現(xiàn)類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.〃狀態(tài)實現(xiàn)類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.〃狀態(tài)更改

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狀態(tài)模式和Proxy代理模式都為客戶端程序提供了一個目標程序代理,真

正的目標程序被代理所隱藏,當客戶端程序調(diào)用目標程序時,首先將調(diào)用請求發(fā)

送給代理,代理才真正調(diào)用目標程序,但是Proxy代理模式和State狀態(tài)模式有

如下區(qū)別:

(D.Proxy代理模式中被調(diào)用的目標程序只有一個,而State狀態(tài)模式中被調(diào)

用的目標程序有多個。

⑵.Proxy代理模式的目的是控制客戶端對目標程序的訪問,而State狀態(tài)模式

是為了根據(jù)條件動態(tài)改變目標程序。

Itrator設計模式

Iterator迭代器模式,提供一種統(tǒng)一的方法訪問-一個容器(container)對象中

各個元素,而又不需暴露該對象的內(nèi)部細節(jié),迭代器模式是為容器而設計。

程序?qū)θ萜鲗ο蟮脑L問必然涉及到遍歷算法,不同的容器遍歷算法是不同的,

List,Stack和Set等等常用容器遍歷元素的算法各不相同。解決容器遍歷算

法差異有兩種方案:第一,可以將遍歷方法塞到容器對象中去,容器承受了過多

的功能,它不僅要負責自己“容器”內(nèi)的元素維護(添加、刪除等等),而且

還要提供遍歷自身的接口;第二,根本不提供容器遍歷算法,讓容器使用者自己

去實現(xiàn)。該方法雖然是省事,卻又將容器的內(nèi)部細節(jié)暴露無遺。迭代器模式的

出現(xiàn),很好的解決了上面兩種情況的弊端,不但將遍歷容器的算法從不同集合

容器類中抽象出來,同時又對外隱藏了容器的具體實現(xiàn)細節(jié)。

迭代器模式由以下角色組成:

1)迭代器角色(Iterator):迭代器角色負責定義訪問和遍歷元素的接口。

2)具體迭代器角色(ConcreteIterator):具體迭代器角色要實現(xiàn)迭代器接口,

并要記錄遍歷中的當前位置。

3)容器角色(Container):容器角色負責提供創(chuàng)建具體迭代器角色的接口。

4)具體容器角色(ConcreteContainer):具體容器角色實現(xiàn)創(chuàng)建具體迭代器

角色的接口——這個具體迭代器角色于該容器的結構相關。

Java集合框架中迭代設計模式的應用:

[java]viewplaincopy

1.〃迭代器,該接口提供了迭代遍歷的通用方法

2.publicinterfaceIterator{

3.booleanhasNext();

4.Objectnext();

5.voidremove();

6.)

7.〃容器迭代化接口,凡是實現(xiàn)此接口的集合容器距可以生成相應的迭代器

8.publicinterfacelterable<T>{

9.〃產(chǎn)生迭代器,將容器對象轉(zhuǎn)換為迭代器對象

10.lterator<T>interator();

11.}

12.〃java集合框架的根接口,該接口繼承了容器迭代化接口,因此java中的集合都可

以被迭代

13.publicinterfaceCollection<E>extendslterable<E>

自定義迭代器,以ArrayList為自定義迭代容器的底層數(shù)據(jù)結構,實現(xiàn)自定義迭

代器的代碼如下:

[java]viewplaincopy

1.publicclassMylteratorimplementsIterable{

2.〃存放數(shù)據(jù)的集合

3.privateArrayListlist;

4.〃負責創(chuàng)建具體迭代器角色的工廠方法

5.publicIteratoriterator(){

6.returnnewItr(list);

7.)

8.〃作為內(nèi)部類的具體迭代器角色

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對象直接調(diào)用iterator()方法就可以將自定義容器對象轉(zhuǎn)

換為迭代器對象。

Iterator模式的優(yōu)點:

(1).實現(xiàn)功能分離,簡化容器接口。讓容器只實現(xiàn)本身的基本功能,把迭代功能

委讓給外部類實現(xiàn),符合類的設計原則。

(2).隱藏容器的實現(xiàn)細節(jié)。

(3).為容器或其子容器提供了一個統(tǒng)一接口,一方面方便調(diào)用;另一方面使得調(diào)

用者不必關注迭代器的實現(xiàn)細節(jié)。

(4).可以為容器或其子容器實現(xiàn)不同的迭代方法或多個迭代方法o

Strategy設計模式

Strategy策略設計模式主要是定義一系列的算法,把這些算法封裝成單獨的類,

在運行時動態(tài)選擇需要的算法,策略模式機制如下:

策略模式例子如下:

[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狀態(tài)模式和Strategy策略模式非常類似,但是有如下區(qū)別:

(1).State狀態(tài)模式重點在于設定狀態(tài)變化,根據(jù)狀態(tài),返回相應的響應。

⑵.Strategy策略模式重點在于根據(jù)需求直接采用設定的策略,即根據(jù)場景選

擇合適的處理算法,而不需要改變狀態(tài)。

Factory設計模式

Factory工廠設計模式為創(chuàng)建對象提供了一種抽象,而對使用者屏蔽了對象創(chuàng)建

的具體細節(jié)過程,工廠模式有三種:簡單工廠模式,抽象工廠模式和工廠方法模

式。

(1).簡單工廠模式:

又叫靜態(tài)工廠模式,簡單工廠只包括一個抽象產(chǎn)品類(該類可以是接口,也可以

是具體的類),所有需要的產(chǎn)品類都是該抽象產(chǎn)品類的子類。簡單工廠模式中工

廠為具體產(chǎn)品工廠,產(chǎn)品為抽象產(chǎn)品,由工廠實例創(chuàng)建產(chǎn)品實例:

?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的反射機制來產(chǎn)生對象實例

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.}

圖形工廠負責具體圖形的對象實例化工作,圖形使用者使用時不需要關心圖形對

象的具體產(chǎn)生過程。

(2).抽象工廠模式:

抽象工廠模式中可以包括多個抽象產(chǎn)品類,每個抽象產(chǎn)品類可以產(chǎn)生出多個具體

產(chǎn)品類,一個抽象工廠用于定義所需產(chǎn)品的組合形式,抽象工廠派生具體工廠類,

這些具體工廠類就是簡單工廠模式中的工廠類,具體工廠類負責具體產(chǎn)品實例的

創(chuàng)建:

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組成,實現(xiàn)一套I0S風格

的軟件皮膚,一套Android風格的軟件皮膚,通過抽象工廠實現(xiàn)軟件皮膚自由切

換例子如下:

[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.}

抽象工廠指定了產(chǎn)品組合形式,具體的工廠產(chǎn)生具體的產(chǎn)品,抽象工廠適用于多個產(chǎn)品相互

組合的情況。

(3).工廠方法模式:

工廠方法中也只包含一個抽象產(chǎn)品類,抽象產(chǎn)品類可以派生出多個具體產(chǎn)品類。

工廠方法定義一個用于創(chuàng)建產(chǎn)品的接口,讓子類決定實例化哪一個類,使得類的

實例化延遲到子類。

^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.}

工廠模式中,重要的是工廠類,而不是產(chǎn)品類。產(chǎn)品類可以是多種形式,多層繼

承或者是單個類都是可以的。但要明確的,工廠模式的接口只會返回一種類型的

實例,這是在設計產(chǎn)品類的時候需要注意的,最好是有父類或者共同實現(xiàn)的接口。

使用工廠模式,返回的實例一定是工廠創(chuàng)建的,而不是從其他對象中獲取的。工

廠模式返回的實例可以不是新創(chuàng)建的,返回由工廠創(chuàng)建好的實例也是可以的。

三種工廠模式的區(qū)別:

簡單工廠:用來生產(chǎn)同一等級結構中的任意產(chǎn)品,對于增加新的產(chǎn)品,無能為

力。

工廠方法:用來生產(chǎn)同一等級結構中的固定產(chǎn)品,支持增加任意產(chǎn)品。

抽象工廠:用來生產(chǎn)不同產(chǎn)品族(由不同產(chǎn)品組合成的一套產(chǎn)品)的全部產(chǎn)品,

對于增加新的產(chǎn)品,無能為力;支持增加產(chǎn)品族。

Prototype設計模式

Prototype原型設計模式是指用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這

些原型來創(chuàng)建新的對象。Prototype原型模式允許一個對象再創(chuàng)建另外一個可定

制的對象,根本無需知道任何關于對象創(chuàng)建的細節(jié)。

Prototype模式例子如下:

[java]viewplaincopy

1.〃抽象原型類

2.abstractclassShapeimplementsColneable{

3.StringshapeName;

4.publicStringgetShapeName(){

5.retunshapeName;

6.)

7.publicvoidsetShapeName(StringshapeName){

8.this.shapeName=shapeName;

9.)

10.〃實現(xiàn)了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的,只有實現(xiàn)了Cloneable

接口的類才可以在其實例上調(diào)用clone。方法,否則會拋出

CloneNotSupportException0

為了獲取對象的一份拷貝,我們可以利用Object類的clone。方法,也可以實

現(xiàn)Cloneable接口,覆蓋基類的clone()方法,在clone。方法中,調(diào)用

super,clone()。

Cloneable接口是一個標記接口,也就是沒有任何內(nèi)容,定義如下:

[java]viewplaincopy

1.packagejava.lang;

2.pubilcinterfaceCloneable{

3.)

更多有關java拷貝方面的內(nèi)容請參考

http://blog.csdn.net/chjttony/article/details/7477346

克隆只是實現(xiàn)Prototype原型模式的一種方法,也可以直接通過new對象的方式

創(chuàng)建原型實例,二者區(qū)別在于:

(1).通過new方式創(chuàng)建的原型和現(xiàn)存的實例對象沒有任何聯(lián)系。

(2).通過克隆方法創(chuàng)建的原型,雖然也是創(chuàng)建新對象,但是將原型實例對象的數(shù)

據(jù)復制到了新的對象中,相當于使用被克隆對象的數(shù)據(jù)作為克隆對象的初始數(shù)

據(jù)。

Prototype原型設計模式和Singleton單類設計模式是相對的,單類模式中,在

整個程序生命周期里,單類模式類的實例對象只有一個。而Prototype原型設計

模式則正好相反,每次都返回的是原型類的不同實例對象。

Java中的深拷貝和淺拷貝

1.淺拷貝與深拷貝概念

⑴淺拷貝(淺克?。?/p>

淺拷貝又叫淺復制,將對象中的所有字段復制到新的對象(副本)中。其中,

值類型字段(java中8中原始類型)的值被復制到副本中后,在副本中的修改不

會影響到源對象對應的值。而引用類型的字段被復制到副本中的還是引用類型的

引用,而不是引用的對象,在副本中對引用類型的字段值做修改會影響到源對象

本身。

淺拷貝簡單歸納就是只復制一個對象,對象內(nèi)部存在指向其他對象,數(shù)組或引用

則不復制。

⑵深拷貝(深克隆)

將對象中的所有字段復制到新的對象中。不過,無論是對象的值類型字段,還

是引用類型字段,都會被重新創(chuàng)建并賦值,對于副本的修改,不會影響到源對象

本身。

深拷貝簡單歸納就是對象內(nèi)部引用的對象均復制。

2.Java中的clone()方法

(1)clone。方法將對象復制了一份并返回給調(diào)用者。一般而言,clone。方法滿

足下面規(guī)范:

①對任何的對象x,都有x.clone。!=x;〃克隆對象與原對象不是同一個對象

②對任何的對象x,都有x.clone().getClass()==x.getClass();〃克隆對象與

原對象的類型一樣

③如果對象x的equals()方法定義恰當,那么x.clone().equals(x);應該成立。

(2)Java中對象的克隆

clone()方法是在Object中定義的,而且是protected的,只有實現(xiàn)了Cloneable

接口的類才可以在其實例上調(diào)用clone。方法,否則會拋出

CloneNotSupportException0

為了獲取對象的一份拷貝,我們可以利用Object類的clone。方法,也可以實

現(xiàn)Cloneable接口,覆蓋基類的clone()方法,在clone。方法中,調(diào)用

super,clone()。

Cloneable接口是一個標記接口,也就是沒有任何內(nèi)容,定義如下:

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()方法時,一定要調(diào)用

super,clone()呢?

在運行時刻,Object中的clone。識別出你要復制的是哪一個對象,然后為此對

象分配空間,并進行對象的復制,將原始對象的內(nèi)容一一復制到新對象的存儲空

間中。

②繼承自java.lang.Object類的clone()方法是淺復制。以下代碼可以證明:

[java]viewplaincopy

1.//Professor沒有實現(xiàn)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實現(xiàn)了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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論