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

下載本文檔

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

文檔簡(jiǎn)介

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

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

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

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

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

軟件設(shè)計(jì)的標(biāo)準(zhǔn)圖標(biāo)式設(shè)計(jì)語(yǔ)言。UML包括

1、用例圖(Usecasediagrams),

2、類圖(Classdiagrams),

3、序歹(J圖(Sequencediagrams),

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

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

6、活動(dòng)圖(Activitydiagrams),

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

8、部署圖(Deploymentdiagrams)

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

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

名稱介紹

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

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

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

部署圖描述一個(gè)系統(tǒng)軟件的拓?fù)浣Y(jié)構(gòu)

行為圖:

名稱介紹

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

用例圖

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

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

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

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

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

等。

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

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

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

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

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

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

1、“開(kāi)閉”原則(Open-ClosedPrinciple)簡(jiǎn)稱OCP,講的是一個(gè)軟件實(shí)體應(yīng)該對(duì)擴(kuò)展開(kāi)放對(duì)

修改關(guān)閉。

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

以被子類代替。

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

于實(shí)現(xiàn)。

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

的單獨(dú)的接口,而不是提供大的總接口。

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

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

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

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

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

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

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

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

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

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

一、創(chuàng)建模式

創(chuàng)建模式是對(duì)類的實(shí)例化過(guò)程的抽象化。在一些系統(tǒng)里,可能需要?jiǎng)討B(tài)的決定怎樣創(chuàng)建對(duì)象,

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

定。

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

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

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

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

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

一起的。

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

造模式,原始模式。

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

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

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

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

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

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

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

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

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

式,門(mén)面模式,橋模式。

三、行為模式

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

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

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

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

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

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

四、簡(jiǎn)單工廠模式

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

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

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

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

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

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

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

下面我們拿實(shí)例來(lái)介紹簡(jiǎn)單工廠模式。如下圖,抽象類型車包括子類火車,汽車,拖拉機(jī)。

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

java代碼如下:

Java代碼

1packagecom.pattern.SimpleFactory;

2/**

3*

4*【描述工工廠類

5*【作者】:yml

6*[時(shí)間]:May20,2012

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

8*

9*/

10publicclassFactory{

11/**

12*

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

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

14*【作者】:yml

15*[時(shí)間]: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*【時(shí)間]:May20,2012

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

38*

39*/

40publicclassAutomobileextendsTrafficMachine{

41?Override

42publicvoidtraffic(){

43//TODOAuto-generatedmethodstub

44}

45)

46packagecom.pattern.SimpleFactory;

47/**

48*

49*【描述】:拖拉機(jī)

50*【作者】:yml

51*【時(shí)間]:May20,2012

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

53*

54*/

55publicclassTractorextendsTrafficMachine(

56?Override

57publicvoidtraffic(){

58//TODOAuto-generatedmethodstub

59}

60/**

61*

62*【描述】:耕地

63*【作者】:yml

64*【時(shí)間]:May20,2012

65*

66*/

67publicvoidplough(){

68}

69)

70packagecom.pattern.SimpleFactory;

71/**

72*

73*【描述】:火車

74*【作者】:yml

75*[時(shí)間):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*[時(shí)間]:May20,2012

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

106*

107*/

108publicabstractclassTrafficMachine{

109publicfloatpower;

110publicfloatload;

111publicabstractvoidtraffic();

112)

113packagecom.pattern.SimpleFactory;

114/**

115*

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

117*【作者]yml

118*[時(shí)間]:May20,2012

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

120*

121*/

122publicclassTypeErrorExceptionextendsException(

123/**

124*

125*/

126privatestaticfinallongserialVersionUID=562037380358960152L;

127publicTypeErrorException(Stringmessage){

128super(message);

129//TODOAuto-generatedconstructorstub

130)

131}

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

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

的產(chǎn)品實(shí)例。

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

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

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

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

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

就是一個(gè)具體的java類來(lái)承擔(dān)。

簡(jiǎn)單工廠的優(yōu)缺點(diǎn):

1、優(yōu)點(diǎn)是因?yàn)榭蛻舳丝梢灾苯酉M(fèi)產(chǎn)品,而不關(guān)心具體產(chǎn)品的實(shí)現(xiàn),免除了客戶端

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

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

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

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

廠方法)進(jìn)行講述。

五、工廠方法模式

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

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

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

類必須改動(dòng),使得整個(gè)工廠的可擴(kuò)展性變得很差,對(duì)開(kāi)閉原則支持不夠。工廠方法模式克服了

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

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

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

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

工廠方法模式的對(duì)簡(jiǎn)單工廠模式進(jìn)行了抽象。有一個(gè)抽象的Factory類(可以是抽象類和接口),

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

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

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

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

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

對(duì)象的工廠類必須實(shí)現(xiàn)這個(gè)接口。

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

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

BuIbCreator與TubeCreator。

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

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

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

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

實(shí)例:延續(xù)上節(jié)中例子來(lái)講,上節(jié)中我們提到造車工廠會(huì)造拖拉機(jī),汽車,火車,在一個(gè)

工廠里明顯不能完成,在現(xiàn)實(shí)世界中,一定是有自己獨(dú)立的工廠來(lái)做。因?yàn)槲覀冎劳侠瓩C(jī),

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

都需要?jiǎng)恿?,都有座椅,車燈等等,那差異就多了,?dòng)力不同,火車可能是電動(dòng)力,汽車是汽

油,拖拉機(jī)是柴油等等。我們利用工廠方法來(lái)抽象這個(gè)造車工廠的模型如下:

通過(guò)以上模型可以看出,工廠方法模式是把原來(lái)簡(jiǎn)單工廠里創(chuàng)建對(duì)象的過(guò)程延遲到了具體

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

六、抽象工廠模式

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

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

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

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

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

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

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

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

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

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

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

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

共同擁有的接口。

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

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

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

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

下面我們來(lái)舉實(shí)例說(shuō)明,我們還是延續(xù)車的例子,我們說(shuō)我們?cè)械脑燔噺S擴(kuò)建,分東北重工

廠和華北機(jī)械廠,這兩個(gè)廠都可以造拖拉機(jī),汽車,火車,但是他們?cè)诠に嚭推放粕隙加兴?/p>

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

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

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

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

七、單例模式

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

單例模式。

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

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

打印機(jī)打印的作業(yè)隊(duì)列,一個(gè)沒(méi)打印完,那么只有在隊(duì)列等待;windows回收站,windows視

窗里回收站有且只有一個(gè)實(shí)例。

單例模式的目的就是有且只提供一個(gè)實(shí)例,所以它有一下幾個(gè)特點(diǎn):

1、單例類只能有一個(gè)實(shí)例;

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

3、單例類必須給所有其他對(duì)象提供這一實(shí)例。

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

上圖可以看出,單例類自己提供一個(gè)實(shí)例給自己。

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

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

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

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

Java代碼?☆€

1packagecom.pattern,singleton;

2/**

3*

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

5*【作者】:yml

6*【時(shí)間】:Jul8,2012

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

8*

9*/

10publicclassHungrySingleton{

11

12〃創(chuàng)建實(shí)例

13privatestaticfinalHungrySingletonsingleton=newHungrySingleton();

14

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

16privateHungrySingleton(){}

17

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

19publicstaticHungrySingletongetlnstanceO{

20returnsingleton;

21)

22

23)

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

Java代碼」

24packagecom.pattern,singleton;

25/**

26*

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

28*【作者】:yml

29*【時(shí)間】:Jul8,2012

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

31*

32*/

33publicclassLazySingleton(

34

35〃創(chuàng)建實(shí)例

36privatestaticLazySingletonsingleton=null;

37

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

39privateLazySingleton(){}

40

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

42synchronizedpublicLazySingletongetlnstanceO{

43〃如果為空就new一個(gè)實(shí)例

44if(singleton==null){

45singleton=newLazySingleton();

46)

47returnsingleton;

48)

49

50)

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

的特點(diǎn)就可以簡(jiǎn)單掌握了。

八、建造模式

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

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

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

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

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

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

建造模式的角色:

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

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

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

們?cè)趹?yīng)用程序調(diào)用下創(chuàng)建產(chǎn)品的實(shí)例包括創(chuàng)建產(chǎn)品各個(gè)零件和產(chǎn)品本身。

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

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

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

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

實(shí)例:

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

外殼。建立以下模型:

莖定者

L1

+道輪胎0

1

+造地盤(pán)0

+造發(fā)動(dòng)機(jī)0

+迨座椅0

+造外殼0

A

-本主:int

能鉆

七o

迨o

發(fā)

機(jī)

造o

迨o

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

1、導(dǎo)演著:

Java代碼四☆€

1packagecom.pattern,builder;

2/**

3*

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

5*【作者】:yml

6*【時(shí)間】:Jul14,2012

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

8*

9*/

10publicclassDirector{

11

12privateBuilderbuilder;

13publicTrafficMachineconstruct()

14{

15builder=newCoachBuilder();

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

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

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

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*【時(shí)間】:Jul14,2012

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

33*

34*/

35publicinterfaceBuilder{

36/**

37*

38*【描述]建造輪胎

39*【作者】:yml

40*【時(shí)間】:Jul14,2012

41*

42*/

43publicvoidbuildTire();

44

45/**

46*

47*【描述]建造底盤(pán)

48*【作者】:yml

49*【時(shí)間】:Jul14,2012

50*

51*/

52publicvoidbuildChassis();

53

54

55*

56*【描述】:建造引擎

57*【作者】:yml

58*【時(shí)間】:Jul14,2012

59*

60*/

61publicvoidbuildEngine();

62

63

64*

65*【描述】:建造座椅

66*【作者】:yml

67*【時(shí)間】:Jul14,2012

68*

69*/

70publicvoidbuildSeat();

71

72/**

73*

74*【描述】:建造外殼

75*【作者】:yml

76*【時(shí)間】:Jul14,2012

77*

78*/

79publicvoidbuildShell();

80

81/**

82*

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

84*【作者】:yml

85*【時(shí)間】:Jul14,2012

86*

87*/

88publicTrafficMachineretrieveResult();

89

90)

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

Java代碼叫

91packagecom.pattern,builder;

92/**

93*

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

95*【作者】:yml

96*【時(shí)間】:Jul14,2012

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

98*

99*/

100publicclassCoachBuilderimplementsBuilder{

101

102privateCoachcoach=newCoach();

103

104?Override

105publicvoidbuildTireO{

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

107coach.setTire(newTire());

108)

109

110?Override

111publicvoidbuildChassis(){

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

113coach.setChassis(newChassis());

114)

115

116?Override

117publicvoidbuildEngine(){

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

coach.setEngine(newEngine());

120)

121

122?Override

123publicvoidbuildSeat(){

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

125coach.setSeat(newSeat());

126)

127

128?Override

129publicvoidbuildShell(){

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

131coach.setShell(newShell());

132)

133

134publicTrafficMachineretrieveResult(){

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

136returncoach;

137)

138

139)

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

Java代碼四☆c

140packagecom.pattern,builder;

141/**

142*

143*【描述】:抽象的車

144*【作者】:yml

145*【時(shí)間】:Jul14,2012

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

147*

148*/

149publicinterfaceTrafficMachine{

150

151)

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

Java代碼口☆€

152packagecom.pattern,builder;

153/**

154*

155*【描述】:客車

156*【作者】:yml

157*【時(shí)間】: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*【描述】:輪胎-一不錯(cuò)具體的實(shí)現(xiàn)

206*【作者】:yml

207*【時(shí)間】:Jul14,2012

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

209*

210*/

211publicclassTire{

212

213)

214packagecom.pattern,builder;

215/**

216*

217*【描述】:底盤(pán)

218*【作者】:yml

219*【時(shí)間】:Jul14,2012

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

221*

222*/

223publicclassChassis{

224

225)

226packagecom.pattern,builder;

227/**

228*

229*【描述】:發(fā)動(dòng)機(jī)

230*【作者】:yml

231*【時(shí)間】:Jul14,2012

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

233*

234*/

235publicclassEngine{

236

237)

238packagecom.pattern,builder;

239/**

240*

241*【描述工座椅

242*【作者】:yml

243*【時(shí)間】:Jul14,2012

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

245*

246*/

247publicclassSeat(

248

249)

250packagecom.pattern,builder;

251/**

252*

253*【描述】:外殼

254*【作者]yml

255*【時(shí)間】:Jul14,2012

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

257*

258*/

259publicclassShell{

260

261)

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

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

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

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

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

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

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

九、原型模式

原型模式(prototype)它是指通過(guò)給定一個(gè)原型對(duì)象來(lái)指明所要?jiǎng)?chuàng)建的對(duì)象類型,然后復(fù)制這個(gè)原型對(duì)象的

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

我們先來(lái)看一下原型模式的模型:

原型模型涉及到三個(gè)角色:

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

抽象原型(prototype):這個(gè)往往由接口或者抽象類來(lái)?yè)?dān)任,給出具體原型類的接口;

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

模擬代碼如下:

Java代碼四☆€

1packageprototype;

2/**

3*

4*作者:yml

5*時(shí)間:2013-7-18下午10:40:49

6*描述:抽象接口

7*/

8publicinterfacePrototypeextendsCloneable{

9

10publicObjectclone();

11

12)

Java代碼四☆c

13packageprototype;

14/**

15*

16*作者:yml

17*時(shí)間:2013-7-18下午10:41:39

18*描述:實(shí)現(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*時(shí)間: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)

以上代碼簡(jiǎn)單描述了原型模式的實(shí)現(xiàn),說(shuō)到這里估計(jì)很多人要跳了,因?yàn)檎f(shuō)到原型模式不能不說(shuō)的問(wèn)題是java

的深拷貝和淺拷貝,那下面我們就來(lái)討論下深拷貝和淺拷貝。

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

深拷貝:拷貝出來(lái)的東西和被拷貝者完全獨(dú)立,相互沒(méi)有影響。

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

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

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

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

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

java語(yǔ)言提供Cloneable接口,在運(yùn)行時(shí)通知虛擬機(jī)可以安全的在這個(gè)類上使用clone()方法,通過(guò)這個(gè)方

法可以復(fù)制一個(gè)對(duì)象,但是Object并沒(méi)有實(shí)現(xiàn)這個(gè)接口,所以在拷貝是必須實(shí)現(xiàn)此標(biāo)識(shí)接口,否則會(huì)拋出

CloneNotSupportedException0

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

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

Java代碼叫☆€

61publicObjectdeepClone(){

62ByteArrayOutputStreambos=newByteArrayOutputStream();

63ObjectOutputStreamoos=newObjectOutputStream(bos);

64oos.writeObject(this);

ByteArrayInputStreambis=newByteArraylnputStream(baos.toByteArray())

66ObjectInputStreamois=newObjectlnputStream(bis);

67returnois.readObject();

68)

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

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

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

十、組合模式

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

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

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

部分對(duì)象和組合起來(lái)的對(duì)象采用同樣的方式來(lái)看待。

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

同時(shí)和葉子節(jié)點(diǎn)具有

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

方為樹(shù)枝節(jié)點(diǎn),它含有其他的節(jié)點(diǎn)。

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

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

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

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

為。

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

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

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

條件是聽(tīng)厭煩了,或者講的人講累了。

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

?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*時(shí)間:2013-7-20下午5:11:41

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

7*/

8publicinterfaceWorker{

9

publicvoiddoSomethingO;

11

12)

Java代碼咱☆€

13packagecomposite;

14/**

15*

16*作者:yml

17*時(shí)間: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*時(shí)間: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()+”,我是一個(gè)領(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*時(shí)間:2013-7-20下午5:49:37

110*描述:測(cè)試類

Ill*/

112publicclassClient{

113

114/**

115*作者:yml

116*時(shí)間: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

運(yùn)行結(jié)果如下:

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

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

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

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

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

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

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

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

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

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

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

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論