java各種設(shè)計模式_第1頁
java各種設(shè)計模式_第2頁
java各種設(shè)計模式_第3頁
java各種設(shè)計模式_第4頁
java各種設(shè)計模式_第5頁
已閱讀5頁,還剩127頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

一、統(tǒng)一建模語言UML

今天開始重溫設(shè)計模式,我想把自己學(xué)習(xí)的過程分享給大家,同時希望大家多多留言來討論,

相互學(xué)習(xí)相互進步。

設(shè)計模式學(xué)習(xí)過程中需要借助UML來建模,把設(shè)計模式圖形化,從而讓我們更好的理解設(shè)計模

式內(nèi)容。什么是UML,UML是統(tǒng)一建模語言(UnifiedModelingLanguage)的縮寫,是當(dāng)今

軟件設(shè)計的標準圖標式設(shè)計語言。UML包括

1、用例圖(Usecasediagrams),

2、類圖(Classdiagrams),

3、序歹(J圖(Sequencediagrams),

4、協(xié)作圖(Collaborationdiagrams),

5、狀態(tài)圖(Statechartdiagrams),

6、活動圖(Activitydiagrams),

7、構(gòu)件圖(Componentdiagrams),

8、部署圖(Deploymentdiagrams)

按照這些圖的用意大致可以將他們分為兩類:結(jié)構(gòu)圖和行為圖

結(jié)構(gòu)圖:

名稱介紹

類圖類圖描述一些類,包的靜態(tài)結(jié)構(gòu)和它們之間的靜態(tài)關(guān)系

對象圖對象圖給出一個系統(tǒng)中的對象快照

構(gòu)件圖描述可以部署的軟件構(gòu)件(比如jar,ejb等)之間的關(guān)系

部署圖描述一個系統(tǒng)軟件的拓撲結(jié)構(gòu)

行為圖:

名稱介紹

用例圖描述一系列的角色和用例以及他們之間的關(guān)系,用來對系統(tǒng)的基本行為進行建

用例圖

活動圖描述不同過程之間的動態(tài)接觸,活動圖是用例圖所描述的行為的具體化表現(xiàn)

狀態(tài)圖描述一系列對象內(nèi)部狀態(tài)及其狀態(tài)變化和轉(zhuǎn)移。

時序圖時序圖是一種相互作用圖,描述不同對象之間信息傳遞的時序

協(xié)作圖是一種相互作用圖,描述發(fā)出信息,接收信息的一系列對象的組織結(jié)構(gòu)

最常用的UML圖有:類圖,用例圖,時序圖UML的建模工具有很多,如Visio,Rose,EA,PD

等。

二、面向?qū)ο笤O(shè)計原則

軟件設(shè)計的核心是提高軟件的可復(fù)用性和可維護性。通常一個軟件之所以可復(fù)用性和可擴展性

差的原因在于設(shè)計過于僵硬,過于脆弱,復(fù)用率低,粘度過高等原因?qū)е碌模@時候需要想辦

法提高可擴展性,靈活性和可插入性,從而提高軟件的可復(fù)用性和可維護性。一般可維護性和

可復(fù)用性不能同時能達到目的,只有遵循一定的設(shè)計原則,設(shè)計出來的系統(tǒng)才能同時滿足可復(fù)

用性和可維護性。面向?qū)ο笤O(shè)計原則主要有如下幾條:

1、“開閉”原則(Open-ClosedPrinciple)簡稱OCP,講的是一個軟件實體應(yīng)該對擴展開放對

修改關(guān)閉。

2、里氏代換原則(LiskovSubstitutionPrinciple)簡稱LSP,講的是任何父類出現(xiàn)的地方都可

以被子類代替。

3、依賴倒轉(zhuǎn)原則(DependencyINversionPrinciple)簡稱DIP,講的是要依賴于抽象不要依賴

于實現(xiàn)。

4、接口隔離原則(InterfaceSegregationPrinciple)簡稱ISP,講的是為客戶端提供盡可能小

的單獨的接口,而不是提供大的總接口。

5、組合/聚合服用原則(Composition/AggregationPrinciple)簡稱CARP,講的是要盡可能使

用組合,聚合來達到復(fù)用目的而不是利用繼承。

6、迪米特法則(LawofDemeter)簡稱LoD,講的是一個軟件實體應(yīng)當(dāng)與盡可能少的其他軟件

實體發(fā)生相互作用。

為什么要在講設(shè)計模式前講設(shè)計原則,是因為設(shè)計模式是面向?qū)ο笤O(shè)計原則的具體指導(dǎo),所以

有了理論和設(shè)計指導(dǎo)我們就可以進入設(shè)計模式學(xué)習(xí)了,設(shè)計模式大家常說的有23中,其實現(xiàn)實

中要多的多,大概分為三類:創(chuàng)建模式,結(jié)構(gòu)模式和行為模式。

三、設(shè)計模式概述

上一節(jié)里提到設(shè)計模式分為創(chuàng)建模式,結(jié)構(gòu)模式和行為模式,這節(jié)我們來學(xué)習(xí)它們的定義以及

它們包含哪些具體的設(shè)計模式。

一、創(chuàng)建模式

創(chuàng)建模式是對類的實例化過程的抽象化。在一些系統(tǒng)里,可能需要動態(tài)的決定怎樣創(chuàng)建對象,

創(chuàng)建哪些對象,以及如何組合和表示這些對象。創(chuàng)建模式描述了怎么構(gòu)造和封裝這些動態(tài)的決

定。

創(chuàng)建模式分為類的創(chuàng)建模式和對象的創(chuàng)建模式兩種。

1、類的創(chuàng)建模式類的創(chuàng)建模式使用繼承關(guān)系,把類的創(chuàng)建延遲到子類,從而封裝了客戶端將

得到哪些具體類的信息,并且影藏了這些類的實例是如何被創(chuàng)建和放在一起的。

2、對象的創(chuàng)建模式對象的創(chuàng)建模式描述的是把對象的創(chuàng)建過程動態(tài)地委派給另外一個對象,

從而動態(tài)地決定客戶端講得到哪些具體的類的實例,以及這些類的實例是如何被創(chuàng)建和組合在

一起的。

創(chuàng)建模式主要包括:簡單工廠模式,工廠方法模式,抽象工廠模式,單例模式,多例模式,建

造模式,原始模式。

二、結(jié)構(gòu)模式

結(jié)構(gòu)模式描述如何將類或?qū)ο蠼Y(jié)合在一起形成更大的結(jié)構(gòu),結(jié)構(gòu)模式也包括類的結(jié)構(gòu)模式和對

象的結(jié)構(gòu)模式。

1、類的結(jié)構(gòu)模式類的結(jié)構(gòu)模式使用繼承把類、接口等組合在一起,以形成更大的結(jié)構(gòu)。當(dāng)一

個類從父類繼承并實現(xiàn)某接口時,這個新的類就把父類的結(jié)構(gòu)和接口的結(jié)構(gòu)結(jié)合起來。類的結(jié)

構(gòu)模式是靜態(tài)的,一個類的結(jié)構(gòu)模式的經(jīng)典列子就是適配器模式。

2、對象的結(jié)構(gòu)模式對象的結(jié)構(gòu)模式描述怎么把各種不同的類型的對象組合在一起,以實現(xiàn)新

的功能的方法。對象的結(jié)構(gòu)模式是動態(tài)的。

結(jié)構(gòu)模式主要包括:適配器模式,缺省適配器模式,合成模式,裝飾模式,代理模式,享元模

式,門面模式,橋模式。

三、行為模式

行為模式是對在不同的對象之間劃分責(zé)任和算法的抽象化。行為模式不僅僅是關(guān)于類和對象的,

而且是關(guān)于它們之間相互作用的。

1、類的行為模式類的行為模式使用繼承關(guān)系在幾個類之間分配行為。

2、對象的行為模式對象的行為模式是使用對象聚合類分配行為的。

行為模式主要包括:不變模式,策略模式,模板方法模式,觀察者模式,迭代子模式,責(zé)任鏈

模式,命令模式,備忘錄模式,狀態(tài)模式,訪問者模式,解釋器模式,調(diào)停者模式。

四、簡單工廠模式

從這節(jié)開始學(xué)習(xí)設(shè)計模式,首先學(xué)習(xí)創(chuàng)建模式,其中工廠模式是創(chuàng)建模式里面最常見也常用的

一種,工廠模式又分簡單工廠模式(SmpieFactory),工廠方法模式(FactoryMethod)和抽象

工廠模式(AbstractorFactory),這里先學(xué)習(xí)最簡單的也就是簡單工廠模式。

簡單工廠模式(SmpleFactory)也稱靜態(tài)工廠方法模式,是工廠方法模式的特殊實現(xiàn)。簡單

工廠模式的一般性結(jié)構(gòu)如下圖:

工廠-------->具體產(chǎn)品

簡單工廠模式就是由一個工廠類根據(jù)傳入的參量決定創(chuàng)建出哪一種產(chǎn)品類型的實例,

下面我們拿實例來介紹簡單工廠模式。如下圖,抽象類型車包括子類火車,汽車,拖拉機。

工廠根據(jù)傳入的參數(shù)來創(chuàng)建具體車的類型。上圖中無法形象地表示抽象類所以用接口代替了。

java代碼如下:

Java代碼

1packagecom.pattern.SimpleFactory;

2/**

3*

4*【描述工工廠類

5*【作者】:yml

6*[時間]:May20,2012

7*【文件】:com.pattern.SimpleFactoryFactory.java

8*

9*/

10publicclassFactory{

11/**

12*

13*【描述】:創(chuàng)建車的實例這個類里面的判斷代碼在實際應(yīng)用中多配置成map,如果用

spring則可以配置在bean的xml內(nèi)

14*【作者】:yml

15*[時間]:May20,2012

16*?throwsTypeErrorException

17*

18*/

publicTrafficMachinecreator(Stringtype)throwsTypeErrorException(

20if(type,equals("Automobile")){

21returnnewAutomobile();

22}elseif(type,equals("Tractor")){

23returnnewTractor();

24}elseif(type,equals(〃Train〃)){

25returnnewTrain();

26}else(

27thrownewTypeErrorException(z/notfind〃+type);

28)

29}

30)

31packagecom.pattern.SimpleFactory;

32/**

33*

34*【描述】:汽車類

35*【作者】:yml

36*【時間]:May20,2012

37*【文件】:com.pattern.SimpleFactoryAutomobile.java

38*

39*/

40publicclassAutomobileextendsTrafficMachine{

41?Override

42publicvoidtraffic(){

43//TODOAuto-generatedmethodstub

44}

45)

46packagecom.pattern.SimpleFactory;

47/**

48*

49*【描述】:拖拉機

50*【作者】:yml

51*【時間]:May20,2012

52*【文件】:com.pattern.SimpleFactoryTractor.java

53*

54*/

55publicclassTractorextendsTrafficMachine(

56?Override

57publicvoidtraffic(){

58//TODOAuto-generatedmethodstub

59}

60/**

61*

62*【描述】:耕地

63*【作者】:yml

64*【時間]:May20,2012

65*

66*/

67publicvoidplough(){

68}

69)

70packagecom.pattern.SimpleFactory;

71/**

72*

73*【描述】:火車

74*【作者】:yml

75*[時間):May20,2012

76*【文件】:com.pattern.SimpleFactoryTrain.java

77*

78*/

79publicclassTrainextendsTrafficMachine{

80privateintnodeNum;〃節(jié)數(shù)

81privateinttrainNum;〃車次

82?Override

83publicvoidtraffic(){

84//TODOAuto-generatedmethodstub

85)

86publicintgetNodeNum(){

87returnnodeNum;

88)

89publicvoidsetNodeNum(intnodeNum){

90this.nodeNum=nodeNum;

91)

92publicintgetTrainNumO{

93returntrainNum;

94)

95publicvoidsetTrainNum(inttrainNum){

96this.trainNum=trainNum;

97)

98)

99packagecom.pattern.SimpleFactory;

100/**

101*

102*【描述】:抽象類車

103*【作者Iyml

104*[時間]:May20,2012

105*【文件】:com.pattern.Simp1eFactoryMachine.java

106*

107*/

108publicabstractclassTrafficMachine{

109publicfloatpower;

110publicfloatload;

111publicabstractvoidtraffic();

112)

113packagecom.pattern.SimpleFactory;

114/**

115*

116*【描述】:類型異常類

117*【作者]yml

118*[時間]:May20,2012

119*【文件】:com.pattern.SimpleFactoryTypeErrorException.java

120*

121*/

122publicclassTypeErrorExceptionextendsException(

123/**

124*

125*/

126privatestaticfinallongserialVersionUID=562037380358960152L;

127publicTypeErrorException(Stringmessage){

128super(message);

129//TODOAuto-generatedconstructorstub

130)

131}

通過以上分析及其代碼列舉可知,簡單工廠類的構(gòu)造有三種角色,它們分別是工廠角

色,抽象產(chǎn)品角色和具體產(chǎn)品角色。工廠類的創(chuàng)建方法根據(jù)傳入的參數(shù)來判斷實例化那個具體

的產(chǎn)品實例。

工廠類角色:這個角色是工廠方法模式的核心,含有與應(yīng)用緊密相連的商業(yè)邏輯。工

廠類在客戶端的直接調(diào)用下創(chuàng)建產(chǎn)品對象,它往往由一個具體的java類來實現(xiàn)。

抽象產(chǎn)品角色:擔(dān)當(dāng)這個角色的是一個java接口或者java抽象類來實現(xiàn)。往往是工

廠產(chǎn)生具體類的父類。

具體產(chǎn)品角色:工廠方法模式所創(chuàng)建的任何對象都是這個角色的實例,具體產(chǎn)品往往

就是一個具體的java類來承擔(dān)。

簡單工廠的優(yōu)缺點:

1、優(yōu)點是因為客戶端可以直接消費產(chǎn)品,而不關(guān)心具體產(chǎn)品的實現(xiàn),免除了客戶端

直接創(chuàng)建產(chǎn)品對象的責(zé)任,簡單工廠模式就是通過這種方法實現(xiàn)了對責(zé)任的分割。

2、缺點是簡單工廠在當(dāng)產(chǎn)品多層次結(jié)構(gòu)復(fù)雜時工廠只能依靠自己,這樣就形成了一

個萬能類,如果這個工廠不能工作了,所有的創(chuàng)建都將不能實現(xiàn),而且當(dāng)產(chǎn)品類別多結(jié)構(gòu)復(fù)雜

的情況下,把所有創(chuàng)建放進一個工廠來,是的后期程序的擴展較為困難。這個困難將在下節(jié)(工

廠方法)進行講述。

五、工廠方法模式

工廠方法模式(FactoryMethod)又稱虛擬構(gòu)造子模式,可以說是簡單工廠的抽象,也可以理解為

簡單工廠是退化了的工廠方法模式,其表現(xiàn)在簡單工廠喪失了工廠方法的多態(tài)性。我們前一節(jié)

中提到當(dāng)產(chǎn)品結(jié)構(gòu)變的復(fù)雜的時候,簡單工廠就變的難以應(yīng)付,如果增加一種產(chǎn)品,核心工廠

類必須改動,使得整個工廠的可擴展性變得很差,對開閉原則支持不夠。工廠方法模式克服了

這些缺點,它定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將實際創(chuàng)建工作推遲到子類當(dāng)中。核心工廠

類不再負責(zé)產(chǎn)品的創(chuàng)建,這樣核心類成為一個抽象工廠角色,僅負責(zé)具體工廠子類必須實現(xiàn)的

接口,這樣進一步抽象化的好處是使得工廠方法模式可以使系統(tǒng)在不修改具體工廠角色的情況

下引進新的產(chǎn)品。一般結(jié)構(gòu)圖如下:

工廠方法模式的對簡單工廠模式進行了抽象。有一個抽象的Factory類(可以是抽象類和接口),

這個類將不在負責(zé)具體的產(chǎn)品生產(chǎn),而是只制定一些規(guī)范,具體的生產(chǎn)工作由其子類去完成。

在這個模式中,工廠類和產(chǎn)品類往往可以依次對應(yīng)。即一個抽象工廠對應(yīng)一個抽象產(chǎn)品,一個

具體工廠對應(yīng)一個具體產(chǎn)品,這個具體的工廠就負責(zé)生產(chǎn)對應(yīng)的產(chǎn)品。

工廠方法模式有如下角色:

抽象工廠(Creator)角色:是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的

對象的工廠類必須實現(xiàn)這個接口。

具體工廠(ConcreteCreator)角色:這是實現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程

序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對象。在上圖中有兩個這樣的角色:

BuIbCreator與TubeCreator。

抽象產(chǎn)品(Product)角色:工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父

類或共同擁有的接口。在上圖中,這個角色是Light。

具體產(chǎn)品(ConcreteProduct)角色:這個角色實現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體

產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對應(yīng)。

實例:延續(xù)上節(jié)中例子來講,上節(jié)中我們提到造車工廠會造拖拉機,汽車,火車,在一個

工廠里明顯不能完成,在現(xiàn)實世界中,一定是有自己獨立的工廠來做。因為我們知道拖拉機,

汽車,火車有很多共性也有很大差異,共性還是車,肯定都是重工生產(chǎn),需要鋼材,車床加工,

都需要動力,都有座椅,車燈等等,那差異就多了,動力不同,火車可能是電動力,汽車是汽

油,拖拉機是柴油等等。我們利用工廠方法來抽象這個造車工廠的模型如下:

通過以上模型可以看出,工廠方法模式是把原來簡單工廠里創(chuàng)建對象的過程延遲到了具體

實現(xiàn)的子類工廠,這時的工廠從一個類變成了一個接口類型。

六、抽象工廠模式

前面我們介紹了簡單工廠,工廠方法模式,這節(jié)來看看抽象工廠模式,抽象工廠模式

(AbstractFactory)是工廠方法里面最為抽象和最具一般性的形態(tài),是指當(dāng)有多個抽象角色時,

使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產(chǎn)品的

具體的情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象。抽象工廠模式和工廠方法模式的最大區(qū)別在于,

工廠方法模式針對的是一個產(chǎn)品等級結(jié)構(gòu);而抽象工廠模式則需要面對多個產(chǎn)品族,從而使得

產(chǎn)品具有二維性質(zhì)。抽象工廠模式的一般示意類圖如下:

下面我們先看抽象工廠的角色都有哪些:

抽象工廠(Creator)角色:是抽象工廠模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對象

的工廠類必須實現(xiàn)這個接口。

具體工廠(ConcreteCreator)角色:這是實現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切

相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對象。

抽象產(chǎn)品(Product)角色:工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父類或

共同擁有的接口。

具體產(chǎn)品(ConcreteProduct)角色:這個角色實現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有

專門的具體工廠創(chuàng)建,它們之間往往一一對應(yīng)。

如果你很留心,你就發(fā)現(xiàn)抽象工廠的角色和工廠方法的角色一樣,其實抽象工廠就是在工廠方

法的基礎(chǔ)上進一步推廣。

下面我們來舉實例說明,我們還是延續(xù)車的例子,我們說我們原有的造車廠擴建,分東北重工

廠和華北機械廠,這兩個廠都可以造拖拉機,汽車,火車,但是他們在工藝和品牌上都有所不

同,我們抽象出以下模型:

通過上圖,我們可以看出,我們系統(tǒng)模型中有個兩個產(chǎn)品族,一個產(chǎn)品族是東北重工廠產(chǎn)出的

所有產(chǎn)品,另一個產(chǎn)品族是華北機械廠生產(chǎn)出的所有產(chǎn)品。我們也可以看出有多少個實現(xiàn)工廠

就有多少個產(chǎn)品族,在工廠角色中有多少工廠方法在同一個產(chǎn)品族類就有多少個具體產(chǎn)品。

七、單例模式

設(shè)計模式的創(chuàng)建模式中前面說了工廠模式,這里我們繼續(xù)來討論設(shè)計模式中另一個創(chuàng)建模式一

單例模式。

單例模式(Singleton)是指確保一個類有且僅有一個實例,而且自行實例化并向整個系統(tǒng)提供

這個實例。這個類我們也稱它為單例類。單例模式的使用在現(xiàn)實世界里很多,比如我們常見的

打印機打印的作業(yè)隊列,一個沒打印完,那么只有在隊列等待;windows回收站,windows視

窗里回收站有且只有一個實例。

單例模式的目的就是有且只提供一個實例,所以它有一下幾個特點:

1、單例類只能有一個實例;

2、單例類必須自己創(chuàng)建自己惟一的實例;

3、單例類必須給所有其他對象提供這一實例。

單例模式的一般結(jié)構(gòu)如下:

上圖可以看出,單例類自己提供一個實例給自己。

由于java語言的特點在單例的實現(xiàn)上有不同的做法,主要體現(xiàn)在單例類如何實例化自己上?;?/p>

于上面三個特點我們可以有兩種創(chuàng)建單例類實例的方法,第一個是提前創(chuàng)建好,用的時候直接

使用;第二種是等到使用的時候再創(chuàng)建實例,業(yè)界稱第一種為餓漢式,后者成為懶漢式。

餓漢式單例設(shè)計模式

Java代碼?☆€

1packagecom.pattern,singleton;

2/**

3*

4*【描述工餓漢式單例模式

5*【作者】:yml

6*【時間】:Jul8,2012

7*【文件】:com.pattern,singleton.HungrySingleton.java

8*

9*/

10publicclassHungrySingleton{

11

12〃創(chuàng)建實例

13privatestaticfinalHungrySingletonsingleton=newHungrySingleton();

14

15〃私有構(gòu)造子

16privateHungrySingleton(){}

17

18〃靜態(tài)工廠方法

19publicstaticHungrySingletongetlnstanceO{

20returnsingleton;

21)

22

23)

懶漢式單例設(shè)計模式

Java代碼」

24packagecom.pattern,singleton;

25/**

26*

27*【描述】:懶漢式單例模式

28*【作者】:yml

29*【時間】:Jul8,2012

30*【文件】:com.pattern,singleton.LazySingleton.java

31*

32*/

33publicclassLazySingleton(

34

35〃創(chuàng)建實例

36privatestaticLazySingletonsingleton=null;

37

38〃私有構(gòu)造子

39privateLazySingleton(){}

40

41〃靜態(tài)工廠方法

42synchronizedpublicLazySingletongetlnstanceO{

43〃如果為空就new一個實例

44if(singleton==null){

45singleton=newLazySingleton();

46)

47returnsingleton;

48)

49

50)

通過上面代碼,可以看出他們之間的區(qū)別,相對而言單例設(shè)計模式比較簡單,我們只要記住它

的特點就可以簡單掌握了。

八、建造模式

建造模式(BuHder)是對象的創(chuàng)建模式,建造模式可以將一個產(chǎn)品的內(nèi)部表象與產(chǎn)品的生產(chǎn)過

程分割開來,從而可以是建造過程生成具有不同內(nèi)部表象的產(chǎn)品對象。一個產(chǎn)品常有不同的組

成成分作為產(chǎn)品的零件,這些零件有可能是對象,也有可能不是對象,通常我們稱作內(nèi)部表象,

不同的產(chǎn)品可以有不同的內(nèi)部表象,也就是不同的零件。使用建造模式可以使客戶端不需要知

道所生成的產(chǎn)品有那些零件,每個產(chǎn)品對應(yīng)的零件彼此有何不同,是怎么建造出來的,以及怎

樣組成產(chǎn)品的。建造模式的簡略圖如下圖所示:

建造模式的角色:

抽象建造者(Builder)角色:給出一個抽象接口,用來規(guī)范產(chǎn)品對象各個組成成分的建造,跟

商業(yè)邏輯無關(guān),但是一般而言,有多少方法產(chǎn)品就有幾部分組成。

具體建造者(ConcreteBuilder)角色:擔(dān)任這個角色的是與應(yīng)用程序緊密相關(guān)的一些類,它

們在應(yīng)用程序調(diào)用下創(chuàng)建產(chǎn)品的實例包括創(chuàng)建產(chǎn)品各個零件和產(chǎn)品本身。

導(dǎo)演者(Director)角色:擔(dān)任這個角色的類調(diào)用具體建造者角色創(chuàng)建產(chǎn)品對象。導(dǎo)演者角色

并沒有產(chǎn)品類的具體知識,真正擁有產(chǎn)品類的具體知識是具體建造者。

產(chǎn)品(Product)角色:產(chǎn)品便是建造中的復(fù)雜對象,一般來說產(chǎn)品對象有多個部分組成,在

一個體統(tǒng)中會有多余一個的產(chǎn)品類。

實例:

我們還舉車的例子,現(xiàn)在要生產(chǎn)一輛客車,客車包括各個部分,如輪胎,底盤,發(fā)動機,座椅,

外殼。建立以下模型:

莖定者

L1

+道輪胎0

1

+造地盤0

+造發(fā)動機0

+迨座椅0

+造外殼0

A

-本主:int

能鉆

七o

迨o

發(fā)

造o

迨o

上面的模型代碼表示如下:

1、導(dǎo)演著:

Java代碼四☆€

1packagecom.pattern,builder;

2/**

3*

4*【描述]導(dǎo)演者

5*【作者】:yml

6*【時間】:Jul14,2012

*【文件】:com.pattern,builder.Director,java

8*

9*/

10publicclassDirector{

11

12privateBuilderbuilder;

13publicTrafficMachineconstruct()

14{

15builder=newCoachBuilder();

16builder.buildTire();〃創(chuàng)建輪胎

17builder.buildChassis();〃創(chuàng)建底盤

builder.buildEngine();〃創(chuàng)建發(fā)動機

builder.buildSeat();〃創(chuàng)建座椅

builder.buildShell();〃創(chuàng)建外殼

21returnbuilder.retrieveResult();

22

23)

24

25)

2、抽象建造者

Java代碼心

26packagecom.pattern,builder;

27/**

28*

29*【描述】:抽象建造者

30*【作者】:yml

31*【時間】:Jul14,2012

32*【文件com.pattern,builder.Builder,java

33*

34*/

35publicinterfaceBuilder{

36/**

37*

38*【描述]建造輪胎

39*【作者】:yml

40*【時間】:Jul14,2012

41*

42*/

43publicvoidbuildTire();

44

45/**

46*

47*【描述]建造底盤

48*【作者】:yml

49*【時間】:Jul14,2012

50*

51*/

52publicvoidbuildChassis();

53

54

55*

56*【描述】:建造引擎

57*【作者】:yml

58*【時間】:Jul14,2012

59*

60*/

61publicvoidbuildEngine();

62

63

64*

65*【描述】:建造座椅

66*【作者】:yml

67*【時間】:Jul14,2012

68*

69*/

70publicvoidbuildSeat();

71

72/**

73*

74*【描述】:建造外殼

75*【作者】:yml

76*【時間】:Jul14,2012

77*

78*/

79publicvoidbuildShell();

80

81/**

82*

83*【描述】:返回產(chǎn)品

84*【作者】:yml

85*【時間】:Jul14,2012

86*

87*/

88publicTrafficMachineretrieveResult();

89

90)

3、實現(xiàn)建造者

Java代碼叫

91packagecom.pattern,builder;

92/**

93*

94*【描述】:客車建造者

95*【作者】:yml

96*【時間】:Jul14,2012

97*【文件】:com.pattern,builder.CoachBuilder.java

98*

99*/

100publicclassCoachBuilderimplementsBuilder{

101

102privateCoachcoach=newCoach();

103

104?Override

105publicvoidbuildTireO{

106//此處根據(jù)實際業(yè)務(wù)寫相關(guān)邏輯

107coach.setTire(newTire());

108)

109

110?Override

111publicvoidbuildChassis(){

112//此處根據(jù)實際業(yè)務(wù)寫相關(guān)邏輯

113coach.setChassis(newChassis());

114)

115

116?Override

117publicvoidbuildEngine(){

118//此處根據(jù)實際業(yè)務(wù)寫相關(guān)邏輯

coach.setEngine(newEngine());

120)

121

122?Override

123publicvoidbuildSeat(){

124//此處根據(jù)實際業(yè)務(wù)寫相關(guān)邏輯

125coach.setSeat(newSeat());

126)

127

128?Override

129publicvoidbuildShell(){

130//此處根據(jù)實際業(yè)務(wù)寫相關(guān)邏輯

131coach.setShell(newShell());

132)

133

134publicTrafficMachineretrieveResult(){

135//此處根據(jù)實際業(yè)務(wù)寫相關(guān)邏輯

136returncoach;

137)

138

139)

4、產(chǎn)品接口(可以沒有)

Java代碼四☆c

140packagecom.pattern,builder;

141/**

142*

143*【描述】:抽象的車

144*【作者】:yml

145*【時間】:Jul14,2012

146*【文件】:com.pattern,builder.TrafficMachine.java

147*

148*/

149publicinterfaceTrafficMachine{

150

151)

5、客車類一實現(xiàn)產(chǎn)品類

Java代碼口☆€

152packagecom.pattern,builder;

153/**

154*

155*【描述】:客車

156*【作者】:yml

157*【時間】:Jul14,2012

158*【文件】:com.pattern,builder.Coach,java

159*

160*/

161publicclassCoachimplementsTrafficMachine

162

163

164privateChassischassis;

165privateTiretire;

166privateEngineengine;

167privateSeatseat;

168privateShellshell;

169

170publicChassisgetChassis(){

171returnchassis;

172)

173publicvoidsetChassis(Chassischassis){

174this.chassis=chassis;

175)

176publicTiregetTireO{

177returntire;

178)

179publicvoidsetTire(Tiretire){

180this.tire=tire;

181)

182publicEnginegetEngineO(

183returnengine;

184}

185publicvoidsetEngine(Engineengine){

186this.engine=engine;

187)

188publicSeatgetSeat(){

189returnseat;

190)

191publicvoidsetSeat(Seatseat){

192this.seat=seat;

193)

194publicShellgetShell(){

195returnshell;

196)

197publicvoidsetShell(Shellshell){

198this.shell=shell;

199}

200

201)

6、部件類

Java代碼□☆c

202packagecom.pattern,builder;

203/**

204*

205*【描述】:輪胎-一不錯具體的實現(xiàn)

206*【作者】:yml

207*【時間】:Jul14,2012

208*【文件】:com.pattern,builder.Tire,java

209*

210*/

211publicclassTire{

212

213)

214packagecom.pattern,builder;

215/**

216*

217*【描述】:底盤

218*【作者】:yml

219*【時間】:Jul14,2012

220*【文件】:com.pattern,builder.Chassis,java

221*

222*/

223publicclassChassis{

224

225)

226packagecom.pattern,builder;

227/**

228*

229*【描述】:發(fā)動機

230*【作者】:yml

231*【時間】:Jul14,2012

232*【文件】:com.pattern,builder.Engine,java

233*

234*/

235publicclassEngine{

236

237)

238packagecom.pattern,builder;

239/**

240*

241*【描述工座椅

242*【作者】:yml

243*【時間】:Jul14,2012

244*【文件】:com.pattern,builder.Seat,java

245*

246*/

247publicclassSeat(

248

249)

250packagecom.pattern,builder;

251/**

252*

253*【描述】:外殼

254*【作者]yml

255*【時間】:Jul14,2012

256*【文件】:com.pattern,builder.Shell,java

257*

258*/

259publicclassShell{

260

261)

通過上面例子我們可以更明確創(chuàng)建模式的各個角色職能和作用,在現(xiàn)實開發(fā)中可能會省略一些,

要根據(jù)實際業(yè)務(wù)來決定,以上是一個產(chǎn)品的例子,事實上多個產(chǎn)品的更為常見。我們將上面的

模型擴展,加入多產(chǎn)品,模型如下:

多產(chǎn)品的實現(xiàn)和單一產(chǎn)品的實現(xiàn)基本一樣,這里就不贅述了。當(dāng)產(chǎn)品為多產(chǎn)品的時候整體結(jié)構(gòu)

有點像抽象工廠模式,但是我們只要把握重點,抽象工廠是在客戶端在不必指定產(chǎn)品的具體的

情況下,創(chuàng)建多個產(chǎn)品族中的產(chǎn)品對象;而建造模式重點在于影藏和封裝復(fù)雜產(chǎn)品的內(nèi)部建造

過程和結(jié)構(gòu),側(cè)重點和用意完全不同,這點要掌握了區(qū)分就很簡單了。

九、原型模式

原型模式(prototype)它是指通過給定一個原型對象來指明所要創(chuàng)建的對象類型,然后復(fù)制這個原型對象的

辦法創(chuàng)建出同類型的對象。原型模式也屬于創(chuàng)建模式。

我們先來看一下原型模式的模型:

原型模型涉及到三個角色:

客戶角色(client):客戶端提出創(chuàng)建對象的請求;

抽象原型(prototype):這個往往由接口或者抽象類來擔(dān)任,給出具體原型類的接口;

具體原型(Concreteprototype):實現(xiàn)抽象原型,是被復(fù)制的對象;

模擬代碼如下:

Java代碼四☆€

1packageprototype;

2/**

3*

4*作者:yml

5*時間:2013-7-18下午10:40:49

6*描述:抽象接口

7*/

8publicinterfacePrototypeextendsCloneable{

9

10publicObjectclone();

11

12)

Java代碼四☆c

13packageprototype;

14/**

15*

16*作者:yml

17*時間:2013-7-18下午10:41:39

18*描述:實現(xiàn)接口

19*/

20publicclassConcretePrototypeimplementsPrototype{

21

?Override

23publicObjectclone(){

24try{

25returnsuper.clone();

}catch(CloneNotSupportedExceptione){

//TODOAuto-generatedcatchblock

28e.printStackTraceO;

29returnnull;

30}

31

32)

33

34)

Java代碼四☆c

35packageprototype;

36/**

37*

38*作者:yml

39*時間:2013-7-18下午10:41:14

40*描述:客戶端

41*/

42publicclassClient{

43privatePrototypeprototype;

44/**

45*@paramargs

46*/

47publicstaticvoidmain(String[]args){

48Clientc=newClient();

c.prototype=c.getNewPrototype(newConcretePrototype());

50

51}

52/**

53*

54*@paramprototype

55*?return

56*/

publicPrototypegetNewPrototype(Prototypeprototype){

58return(Prototype)prototype,clone();

59)

60)

以上代碼簡單描述了原型模式的實現(xiàn),說到這里估計很多人要跳了,因為說到原型模式不能不說的問題是java

的深拷貝和淺拷貝,那下面我們就來討論下深拷貝和淺拷貝。

淺拷貝:是指拷貝引用,實際內(nèi)容并沒有復(fù)制,改變后者等于改變前者。

深拷貝:拷貝出來的東西和被拷貝者完全獨立,相互沒有影響。

引用一哥們舉的例子(博客地址忘記了)

有一個人叫張三,人們給他取個別命叫李四,不管張三還是李四都是一個人,張三胳膊疼,李四也是一個樣的

不爽。這個就是淺拷貝,只是個別名而已。

同樣還是有一個人叫張三,通過人體克隆技術(shù)(如果法律允許)得到一個李四,這個李四和被克隆的張三完全

是兩個人,張三就是少個胳膊,李四也不會感到疼痛。這個就是深拷貝。

java語言提供Cloneable接口,在運行時通知虛擬機可以安全的在這個類上使用clone()方法,通過這個方

法可以復(fù)制一個對象,但是Object并沒有實現(xiàn)這個接口,所以在拷貝是必須實現(xiàn)此標識接口,否則會拋出

CloneNotSupportedException0

但是clone()方法出來的默認都是淺拷貝,如果要深拷貝,那么可以考慮自己編寫clone方法,但是深度很難

控制,編寫這個clone方法也不是最佳方案,還有個比較好的方案就是串行化來實現(xiàn),代碼如下:

Java代碼叫☆€

61publicObjectdeepClone(){

62ByteArrayOutputStreambos=newByteArrayOutputStream();

63ObjectOutputStreamoos=newObjectOutputStream(bos);

64oos.writeObject(this);

ByteArrayInputStreambis=newByteArraylnputStream(baos.toByteArray())

66ObjectInputStreamois=newObjectlnputStream(bis);

67returnois.readObject();

68)

這樣就可以實現(xiàn)深拷貝,前提是對象實現(xiàn)java.io.Serializable接口。

注意:除了基本數(shù)據(jù)類型外,其他對象默認拷貝都是淺拷貝,String類型是個例外,雖然是基本類型,但是也

是淺拷貝,這個跟它實際在java內(nèi)存存儲情況有關(guān)。超出了設(shè)計模式討論范圍,大家可自行查看相關(guān)資料。

十、組合模式

這節(jié)開始學(xué)習(xí)結(jié)構(gòu)模式,結(jié)構(gòu)模式包括:組合模式、門面模式、適配器模式、代理模式、裝飾

模式、橋模式、享元模式。從組合模式開始學(xué)習(xí)。

組合模式(Composite)就是把部分和整體的關(guān)系用樹形的結(jié)構(gòu)來表示,從而使客戶端能夠把

部分對象和組合起來的對象采用同樣的方式來看待。

樹圖結(jié)構(gòu)一般包含一個根節(jié)點,若干個樹枝和葉子節(jié)點。如下圖:

同時和葉子節(jié)點具有

樹結(jié)構(gòu)的類圖,其實就是組合模式的簡略類圖,最上面為抽象節(jié)點,左下方為葉子節(jié)點,右下

方為樹枝節(jié)點,它含有其他的節(jié)點。

通過以上結(jié)構(gòu)圖可以看出,組合模式有以下角色:

1、抽象構(gòu)建角色(component):作為抽象角色,給組合對象的統(tǒng)一接口。

2、樹葉構(gòu)建角色(leaf):代表組合對象中的樹葉對象。

3、樹枝構(gòu)建角色(composite):參加組合的所有子對象的對象,并給出樹枝構(gòu)構(gòu)建對象的行

為。

組合模式在現(xiàn)實中使用很常見,比如文件系統(tǒng)中目錄和文件的組成,算式運算,android里面的

view和viewgroup等控件,淘寶產(chǎn)品分類信息的展示等都是組合模式的例子。還有個故事:從

前山里有座廟,廟里有個老和尚,老和尚對象小和尚講故事說,從前山里有個廟……退出循環(huán)的

條件是聽厭煩了,或者講的人講累了。

這個模式的舉例最多的是公司員工的例子。我們這里也以故事雇員為例子來描述:

?interface?

Worker0..*

+doSomettiingQ:void

Employe

+doSomething{):voidlist:List<Wo<xer>

+doSomething{):void

+3dd(Worter):void

+remove{Worter):void

+getChild{int):Worter

Java代碼Ei☆€

1packagecomposite;

2/**

3*

4*作者:yml

5*時間:2013-7-20下午5:11:41

6*描述:員工和領(lǐng)導(dǎo)的統(tǒng)一接口

7*/

8publicinterfaceWorker{

9

publicvoiddoSomethingO;

11

12)

Java代碼咱☆€

13packagecomposite;

14/**

15*

16*作者:yml

17*時間:2013-7-20下午5:59:11

18*描述:普通員工類

19*/

20publicclassEmployeimplementsWorker{

21

22privateStringname;

23

24publicEmploye(Stringname){

25super();

26this,name=name;

27}

?Override

29publicvoiddoSomethingO(

30System,out.printin(toString());

31)

32

33

34?Override

35publicStringtoString(){

36//TODOAuto-generatedmethodstub

37return〃我叫〃+getName()+〃,就一普通員工!〃;

38}

39

40publicStringgetName(){

41returnname;

42)

43

44publicvoidsetName(Stringname){

45this.name=name;

46)

47

48)

Java代碼

49packagecomposite;

50

51importjava.util.Iterator;

52importjava.util.List;

53importjava.util,concurrent.CopyOnWriteArrayList;

54

55/**

56*

57*作者:yml

58*時間:2013-7-20下午5:14:50

59*描述:領(lǐng)導(dǎo)類

60*/

61publicclassLeaderimplementsWorker{

privateList<Worker>workers=newCopyOnWriteArrayList<Worker>();

63privateStringname;

64

65publicLeader(Stringname){

66super();

67this,name=name;

68)

69publicvoidadd(Workerworker){

70workers,add(worker);

71)

72

73publicvoidremove(Workerworker){

74workers,remove(worker);

75}

76

77publicWorkergetChild(inti){

78returnworkers,get(i);

79)

80?Override

81publicvoiddoSomethingO{

82System,out.printin(toString());

83Iterator<Worker>it=workers,iterator();

84while(it.hasNext()){

85it.next().doSomethingO;

86)

87

88

89

90

91?Override

92publicStringtoString(){

93//TODOAuto-generatedmethodstub

94return〃我叫〃+getName()+”,我是一個領(lǐng)導(dǎo),有"+workers.size()+”下屬。

〃.

95)

96publicStringgetName(){

97returnname;

98)

99

100publicvoidsetName(Stringname){

101this,name=name;

102)

103

104}

Java代碼Q

105packagecomposite;

106/**

107*

108*作者:yml

109*時間:2013-7-20下午5:49:37

110*描述:測試類

Ill*/

112publicclassClient{

113

114/**

115*作者:yml

116*時間:2013-7-20下午5:49:32

117*描述:

118*/

119publicstaticvoidmain(String[]args){

120//TODOAuto-generatedmethodstub

121Leaderleaderl=newLeader(〃張三〃);

122Leaderleader2=newLeader(〃李四〃);

123Employeemployel=newEmploye(〃王五〃)

124Employeemploye2=newEmploye(〃趙六〃)

125Employeemploye3=newEmploye(〃陳七〃)

126Employeemploye4=newEmploye(〃徐八〃)

127leaderl.add(leader2);

128leaderl.add(employe1);

129leaderl.add(employe2);

130leader2.add(employes);

131leader2.add(employe4);

132leaderl.doSomething();

133

134

運行結(jié)果如下:

我叫張三,我是一個領(lǐng)導(dǎo),有3個直接下屬。

我叫李四,我是一個領(lǐng)導(dǎo),有2個直接下屬。

我叫陳七,就一普通員工!

我叫徐八,就一普通員工!

我叫王五,就一普通員工!

我叫趙六,就一普通員工!

上面員工關(guān)系的的樹形結(jié)構(gòu)如下:

上面例子給出的組合模式抽象角色里,并沒有管理子節(jié)點的方法,而是在樹枝構(gòu)建角色,這種

模式使得葉子構(gòu)建角色和樹枝構(gòu)建角色有區(qū)分,客戶端要分別對待樹葉構(gòu)建角色和樹枝構(gòu)建角

色,好處是客戶端對葉子節(jié)點不會調(diào)用管理的方法,當(dāng)調(diào)用時,在編譯時就會報錯,所以也稱

安全模式。相對安全模主還直「枇馴楔也就是在抽象角色里面添加管理方法,如下圖:

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論