版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 昆明醫(yī)科大學(xué)海源學(xué)院《應(yīng)急管理信息系統(tǒng)》2023-2024學(xué)年第一學(xué)期期末試卷
- 江西財經(jīng)職業(yè)學(xué)院《飛機結(jié)構(gòu)基礎(chǔ)》2023-2024學(xué)年第一學(xué)期期末試卷
- 湖南三一工業(yè)職業(yè)技術(shù)學(xué)院《新課程理念與地理課程改革》2023-2024學(xué)年第一學(xué)期期末試卷
- 湖南安全技術(shù)職業(yè)學(xué)院《有限元方法》2023-2024學(xué)年第一學(xué)期期末試卷
- 【物理】《流體壓強與流速的關(guān)系》(教學(xué)設(shè)計)-2024-2025學(xué)年人教版(2024)初中物理八年級下冊
- 高考物理總復(fù)習(xí)《恒定電流》專項測試卷含答案
- 重慶工信職業(yè)學(xué)院《廣告策劃與設(shè)計》2023-2024學(xué)年第一學(xué)期期末試卷
- 鄭州電力職業(yè)技術(shù)學(xué)院《應(yīng)用技術(shù)開發(fā)》2023-2024學(xué)年第一學(xué)期期末試卷
- 中國民用航空飛行學(xué)院《信息系統(tǒng)審計》2023-2024學(xué)年第一學(xué)期期末試卷
- 鄭州美術(shù)學(xué)院《建筑設(shè)備自動化課程設(shè)計》2023-2024學(xué)年第一學(xué)期期末試卷
- 餐飲行業(yè)智慧餐廳管理系統(tǒng)方案
- 2025年度生物醫(yī)藥技術(shù)研發(fā)與許可協(xié)議3篇
- 電廠檢修安全培訓(xùn)課件
- 殯葬改革課件
- 雙方個人協(xié)議書模板
- 車站安全管理研究報告
- 瑪米亞RB67中文說明書
- 五年級數(shù)學(xué)(小數(shù)四則混合運算)計算題專項練習(xí)及答案
- 2024年鋼鐵貿(mào)易行業(yè)前景分析:鋼鐵貿(mào)易行業(yè)發(fā)展趨勢推動行業(yè)可持續(xù)發(fā)展
- 節(jié)前物業(yè)安全培訓(xùn)
- 初中中考英語總復(fù)習(xí)《代詞動詞連詞數(shù)詞》思維導(dǎo)圖
評論
0/150
提交評論