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

下載本文檔

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

文檔簡介

java中的23種設(shè)計模式

1.設(shè)計模式(超級詳細)內(nèi)容簡介

有感于設(shè)計模式在日常開發(fā)中的重要性,同時筆者也自覺對設(shè)計模式小有心得,故筆者*寫二十三種設(shè)計模式的簡單例子、并整理二十三種設(shè)計模式的理論部分,綜合匯總成這份Java設(shè)計模式(瘋狂Java聯(lián)盟版),希望對大家有所幫助。

本份幫助文檔主要是為了向讀者介紹二十三種設(shè)計模式,包括模式的描述,適用性,模*的組成部分,并附帶有簡單的例子和類*,目的是為了讓讀*了解二十三種*計模式,并能方便的查閱各種設(shè)計模*的用法及注意點。

所附的例子非常簡單,慢慢的引導(dǎo)讀者從淺到深了解設(shè)計模式,并能從中享受設(shè)計的樂趣。

由于每個人對設(shè)計*式的理解都不盡一致,因此,可能本文檔的例子*有不恰當(dāng)?shù)牡胤?,還望各位讀者指出不恰當(dāng)?shù)牡胤?。歡迎登錄瘋狂J*va聯(lián)盟進行技術(shù)交流,瘋狂Java聯(lián)盟的論壇宗旨是:

所有的技術(shù)發(fā)帖,均有回復(fù)。

瘋狂Java聯(lián)盟網(wǎng)址:筆者簡介筆者曾師從李剛老師學(xué)習(xí)Java,現(xiàn)居廣州。對Java軟件開發(fā)、各種Java開源技術(shù)都非常感興趣,曾參與開發(fā)、主持*發(fā)過大量Java、JavaEE項目,對Java、Java*E項目有一定認(rèn)識*見解。歡迎大家與筆者就Java、JavaEE相*方面進行技術(shù)交流。

筆者現(xiàn)為瘋狂Jav*聯(lián)盟的總版主(論壇ID:楊恩雄),也希望通過該平臺與大家分享Java、JavaEE技術(shù)、*得。

本人郵箱:yangenxiong@163.com

聲明

本文檔編寫、制作過程中得到了瘋狂Java聯(lián)盟、以及筆者學(xué)習(xí)工作過程大量朋友的支持,大家都抱著一個目的:為國內(nèi)軟件軟件開發(fā)事業(yè)作出綿薄貢獻。

我們在此鄭重宣布,本文檔遵循Apache2.0協(xié)議。在完整保留全部文本(包括本版權(quán)頁),并且不違反Apache2.0協(xié)議的前提下,允許和鼓勵任何人進行全文轉(zhuǎn)載及推廣,我們放棄除署名權(quán)外的一切權(quán)利。1.1創(chuàng)建型模式AbstractFactory(抽象工廠)FactoryMethod(工廠方法)Singleton(單態(tài)模式)Builder(建造者模式)Protot*pe*原型模式)1.1.1工廠方法

*義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪一個類。FactoryMethod使一個類的實例*延遲到其子類。

適用性

1.當(dāng)一個類不知道它所必須創(chuàng)建的對象的類的時候。

2.當(dāng)一個類希望由它的子類來指定它所創(chuàng)建的對象的時候。

3.當(dāng)*將創(chuàng)建對象的職責(zé)委托給多個幫助*類中的某一個,并且希望將哪一個幫助子類是代理者這一信息局部化的候。

參與者

1.Product

定義工廠方法所創(chuàng)建的對象的接口。

2.ConcreteProduct

實現(xiàn)Product接口。

3.Creator

聲明工廠方法,該方法返回一個Product類型的對象*

Creator也可以定義一個工廠方法的缺省實現(xiàn),它返回一個缺省的ConcreteProduct對象。

可以調(diào)用工廠方法以創(chuàng)建一個Product對象。

4.ConcreteCreator

重定義工廠方法以返回一個ConcreteProduct實例。

類圖

例子*roduct

publicinterfaceWork{

voiddoWork();}ConcreteProduct

publicclassStudentWorkimplementsWork{

publicvoiddoWork(){

System.out.println("學(xué)生*作業(yè)!");

}

}

publicclassTeacherWorkimplementsWork{

publicvoiddoWork(){

System.out.println("老師審批作業(yè)!");

}

}Creator

publicinterfaceIWorkFactory{

Workget*ork();}Concre*eCreator

pu*licclassStudentWorkFactoryimplementsIWorkFactory{

publicWorkgetWork(){

*eturnnewStudentWork();

}

}

publicclassTeacherWorkFactoryimplementsIWorkFactory{

publicWorkgetWork(){

returnnewTeacherWork();

}

}Test

publicclassTest{

publicstaticvoidm*in(Strin*[]args){

IWorkFactorystudentWorkFactory=newStudentWorkFactory();

studentWorkFactory.getWork().d*Work();

IWorkFactoryteacherWorkFactory*newTeacherWorkFactory();

teacherWorkFactory.g*tWork().*oWork();

}

}result

學(xué)生做作業(yè)!老師審批作業(yè)!1.1.2抽象工廠

提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類。

適用性

1.一個系統(tǒng)要獨立于它的*品的創(chuàng)建、組合和表示時。

2.一個系統(tǒng)要由多個產(chǎn)品系列中的一個來配置時。

3.當(dāng)你要強調(diào)一系列相關(guān)的產(chǎn)品對象的設(shè)計以便進行聯(lián)合使用時*

4*當(dāng)你提供一個產(chǎn)品類庫,而只想顯示它們*接口而不是實現(xiàn)時。

參與者

1.Ab*tractFactory

聲明一個創(chuàng)建抽象產(chǎn)品對象的操作接口。

2.ConcreteFactory

實現(xiàn)創(chuàng)建具體產(chǎn)品對象的操作。

*.AbstractProduct

為一類產(chǎn)品對象聲明一個接口。

4.ConcreteProdu*t

定義一個將被相應(yīng)的具體工廠創(chuàng)建的產(chǎn)品*象。

實現(xiàn)*bstractProduct接口。

5.Client

僅使用由AbstractFactory和AbstractProduc*類聲明的接口

類圖

例子*bstractFactory

publicinterfaceIAn*malFactory{

ICatcreateCat();

IDogcre*teDog();}ConcreteFactory

p*blicclassBlackAnimalFactoryimplem*ntsIAnimalFactory{

publicICatcreateCat(){

retur*newBlackCat();

}

publicIDogcreateDog(){

returnnewBlackDog();

}

}

publicclassWhiteAnimalFac*oryimp*ementsIAnimalFactory{

publicICatcreateCat(){

returnnewWhiteCat();

}

publicIDogcre*teDog(){

returnnewWhiteDog();

}

}Abstrac*Product

publicinterfaceICat{

voideat();}

publicinterfaceIDog{

voideat();}Concrete*roduct

publicclassBlack*atimplementsICat{

publicvoideat(){

System.out.println("Thebl*ckcatiseating!");

}

}

publicclassWhiteCatimplements*Cat{

publicvoideat(){

Sy*tem.out.prin*ln("Thew*itecatiseating!*);

}

}

publicclassBlackDogimplementsIDog{

publicvoideat(){

System.out.println("Theblackdogiseating");

}

}

publicclassWhiteDogimplementsIDog{

publicvoideat(){

System.out.println("Thewhitedogiseat*ng!");

}

}Client

publicstaticvoidmain(String[]args){

IAnimalFactoryblackAnimalFa*tory=newBlackAnimalFactory();

ICatblackCat=blackAnimalFactory.createCat();

blackCat.eat();

IDogblackD*g=blackAnimalFactory.createDog();

blackDog.eat();

IAnimalFactorywhiteAnimalF*ctory=newWhiteAnimalFactory();

ICatwhiteCat=whiteAnimalFactory.createCat();

whiteCat.eat();

IDog*hiteDog=whiteAnimalFactory.createDog();

whiteDog.eat();}res*lt

Thebla*kcatiseating!Th*blackdogiseatin*!Thewhitecatiseating!Thewhitedogis*ating!1.1.3建造者模式

將一個復(fù)雜對象的構(gòu)*與它的表示分離,使*同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

適用性

1.當(dāng)創(chuàng)建復(fù)雜對象的算法應(yīng)該獨立于該對象的組成部分以及它們的裝配方式時。

*.當(dāng)構(gòu)造過程必須允*被構(gòu)造的對象有不同*表示時。

參與者

1.Builder

為創(chuàng)建一個Product對象的各個部件指定抽象接口。

2.ConcreteBuilder

實現(xiàn)Buil*er的接口以構(gòu)造和裝配該產(chǎn)品的各個部件。

定義并明確它所創(chuàng)建的表示*

提供一個檢索產(chǎn)品的接口。

3.Director

構(gòu)造一個使用Builder接口的對象。

4.Product

表示被構(gòu)造的復(fù)雜對象。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程。

包含定義組成部件的類,包括將這些部件裝配成最終產(chǎn)品的接口。

類圖

例子Buil*er

publicinterfacePersonBuilder{

voidbuildHead();

v*idbuildBody();

voidbuildFoot()*

PersonbuildPerson();}ConcreteBuilder

publicclassManBuilderimplementsPersonB*ilder{

Personperson;

publicManBuilder(){

person=ne*Man();

}

publ*cvoidbuild*ody(){

perso*.setBody("建造男人的身體");

}

publicvoidbuildFoot(){

person.setFo*t("建造男人的腳");

}

publicvoidbuildHead(){

pers*n.setHead("建造*人的頭");

}

*ublicPersonbuildPerson(){

retur*person;

}}Dir*ctor

publicclassPersonDirec*or{

publicPersonconstructPerson(PersonBuilderpb){

pb.buildHead();

pb.buildBody();

pb.buildFoot();

returnpb.buildPerson();

}}Product

publicclassPerson{

privateStringhead;

privateStringbody;

privateStringfoot;

publicStringgetH*ad(){

returnhead;

}

publicvoidsetHead(Stringhea*){

this.head=head;

}

publicStringgetBody(){

returnbody;

}

publicvoidsetBody(Stringbody){

this.b*dy=body;

}

publicStringgetFoot(){

returnfoot;

}

publicvoidsetFoot(Stringfoot){

t*is.foot=foot;

}}

publicclassManextendsPerson{

}Test

publ*cclassTest{

publicstaticvoidmain(String[]ar*s){

PersonDirectorpd=newPersonDirector();

Personperson=pd.constructPerson(newManBuilder());

System*out.println(person.getBody());

System.out.println(person.getFoot());

System.out.println(person.getHead());

}}result

建造男人*身體建造男*的腳建造男人的頭1.1.4單態(tài)模式

保證一個類僅有一個實例,*提供一個訪問它的全局訪*點。

適用性

1.當(dāng)類只能有一個*例而且客戶可以從一個眾所周知的訪問點訪問它時。

2.當(dāng)這個唯一實例應(yīng)該是通過子類化可擴展的,并且客戶應(yīng)該無需更改代碼就能使用一個擴展的實例時。

參與者

Singleton

定義一個Instance操作,允許客戶訪問它的唯一實例。Instance是一個類操作。

可能負*創(chuàng)建它自己的唯一實例。

類圖

例子Singleton

publicclassSingleton{

privatestaticSingletonsing;

privateSingleton(){

}

publicst*ticSingletonget*nstance(){

if(sing==null){

sing=newSingleto*();

}

returnsing;

}}Test

publicclassTest{

publicstaticvoid*ain(*tring[]args){

Singletonsing=Singleton.getInstance();

Singletonsi*g2=Singleton.getI*stance();

System.out.println(sing);

System.out.pr*ntln(sing2);

}}result

singleton.Singleton@1c78e57singleton.Singleton@1c78e571.1.5原型模式

用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。

適用性

1.當(dāng)一個系統(tǒng)應(yīng)該獨立于它的產(chǎn)品創(chuàng)*、構(gòu)成和表示時。

2.當(dāng)要實例化的類是在運行時刻指定時,例如,通過動態(tài)裝載。

3.為了避免創(chuàng)建一個與產(chǎn)品類層次平行的工廠*層次時。

4.當(dāng)一個類的實例只能有幾個不同狀態(tài)組合中的一種時。

建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實例化該類更方便一些。

參與者

1.Prototype

聲明一個克隆自身的接口。

2.ConcretePrototype

實現(xiàn)一個克隆自身的操作。

3.Client

讓一個原型克*自身從而創(chuàng)建一個新的對象。

類圖

例子Prototype

publicclassPrototypeimplementsCloneable{

privateStringname;

publicvoidsetName(Stringname){

=name;

}

publicStringgetName(){

return;

}

publicObjectclone(){

try{

returnsuper.clone();

}catch(Exceptione){

e.printStackTrace();

returnnull;

}

}}ConcretePrototype

publ*cclassConcretePrototypeextend*Prototype{

publicConcretePrototype(Stringname){

setName(name);

}}Client

publicclas*Test{

publicstaticvoidmain(String[]args){

Prototypepro=newConcretePrototy*e("prototype");

Prototypepro2=(Prototype)pro.clone();

*ystem.out.println(pro.getName()*;

System.out.println(pro2.getName());

}}result

prototypeprototype

1.2結(jié)構(gòu)型模式Adapter*適配器模式*Bridge(橋接模*)Composite(組合模式)Decorator(裝飾模式)Facade(外觀模式)Flyweight(享元模式)Proxy(代理模式)1.2.1適配器模式

將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。Adapter模式使得原本由于接口*兼容而不能一起工作的那*類可以一起工作。

適用性

1.你想使*一個已經(jīng)存在的類,而它的接口不符合你的需求。

2.你想創(chuàng)建一個可以復(fù)用的類,該類可以與其他不相關(guān)的類或不可預(yù)見的類(即那*接口

可能不一定兼容的類)協(xié)同工作。

*.(僅適用于對象Adapter)你想使用一些已經(jīng)存在的子類,但是不可能對每一個都進行

子類化以匹配它們的接口。對象適配器可以適配它的父類接口。

參與者

1.Target

定義Client使用的與特定領(lǐng)域相關(guān)的接口。

2.Client

與符合Target接口的對象協(xié)同。

3.Adapt*e

定義一個已經(jīng)存在的接口,這個接口需要適配。

4.Adapter

對Adaptee的接口與Target接口進行適配

類圖

例子Target

publicinterfaceTarget{

voidadapteeMethod();

voidadapterMethod();}Adaptee

publicclassAdaptee{

publicvoidadapteeMethod(){

Syste*.out.p*intln("Adapteemethod!");

}}Adapt*r

publicclas*Adapterimplement*Target{

privateAdap*eeadaptee;

publicAdapter(Adapteeadaptee){

this.adapte*=adaptee;

}

publicvoidadapteeMethod(){

adaptee.adapteeMethod();

}

publicvoidadapterMethod(){

*ystem.out.println("Adaptermethod!");

}}Client

publiccla*sTest{

publicstati*voidmain(String[]args){

Targettarget=newAdapter(newAdaptee());

tar*et.adapteeMethod();

target.adapterM*thod();

}}result

Adapteemethod!Adaptermethod!1.2.2橋接模式

將抽象部分與它*實現(xiàn)部分分離,使它們都可以獨立地變化。

適用性

1.你不希望在抽*和它的實現(xiàn)部分之間有一個固定的綁定關(guān)系。

例如這種情況可能是因為,在程序運行時刻實現(xiàn)部分應(yīng)可以*選擇或者切換。

2.類的抽象以及它的實現(xiàn)都應(yīng)該可以通*生成子類的方法加以擴充。

這時Bridge模式使你可以對不同的抽象接口和實現(xiàn)部分進行組合,并分別對它們進行擴充。

3.對一個抽象的實現(xiàn)部分的修改應(yīng)對客戶不產(chǎn)生影響,即客戶的代碼不必重新編譯。

4.正如在意圖一節(jié)的第一個類圖中所示的那樣,有許多類要生成。

這*一種類層次結(jié)構(gòu)說明你必須將一個對象分解成兩個部分。

5.*想在多個對象間共享實現(xiàn)(可能使用引用計數(shù)),但同時要求客戶并不知*這一點。

參與者

1.Abstraction

定義抽象類的接口。

維護一個指向Implementor類型對象的指針。

2.RefinedAbstraction

擴充由Abstraction定義的接口。

3.Implementor

定義實現(xiàn)類的接口,該接口不一定要與Ab*traction的接口完全一致。

事實上這兩個接口可以完全不同。

*般來講,Implementor接口僅提供基本操作,而Abstraction則定義了基于這些基本操作的較高層次的操作。

4.ConcreteImplementor

*現(xiàn)Implementor接口并定義它的具體實現(xiàn)。

類圖

例子Abstr*ction

publicabstractclassPerson{

privateClothingclothing;

pr*vateStringtype;

publicClothinggetClothing(){

returnclothing;

}

publi*voidsetClothing(){

this.clothing=*lothingFactory.getClothing();

}

publicvoidsetType(Stringtype){

t*is.type=type;

}

publicStringgetType(){

returnthis.ty*e;

}

publicabstractvoiddress();}RefinedAbstraction

publicclassManextendsPerson{

publicMan(){

setType("男人");

}

publicvoiddress(){

Clothingclothing=get*lothing();

clothing.personDressCloth(this);

}}

publicclassLadyextendsPerson{

publicLady(){

setTyp*("女人");

}

publicvoiddress(){

Cloth*ngclothing=getClothing();

c*othing.personDressCloth(this);

}}Implemento*

publicabstractclassClothing{

publicabstractvoidpersonDressC*oth(*ersonperson);}ConcreteImplemento*

publicclass*ack*textendsClothing{

publicvoidpersonDressCloth(Personperson){

System.out.println(person.getType()+"穿馬甲");

}}

publiccl*ssTrouserextendsClothing{

publicvoidpersonDressCloth(Personperson){

System.ou*.println(*erson.getType()+"穿褲子");

}}Test

publicclassTe*t{

publics*aticvoidmain(String[]args){

Personman=newMan();

Personlady=newLady();

Clothingjacket=newJa*ket();

Clot*ingtrouser=newTrouser();

jacket.personDressCloth(man);

trouser.personDressCloth(man);

j*cket.personDressCloth(lady);

trouser.personDressCloth(lady);

}}result

男人穿馬甲男人穿褲子女人穿馬甲女人穿褲子1.2.3組合模式

將對象組合成樹形結(jié)構(gòu)以表示"部分-整體"的層次結(jié)構(gòu)。"Composite使得用戶對單個對象和組合對*的使用具有一致性。"

適用性

1.你想表示對象的部分-整*層次結(jié)構(gòu)。

2.你希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象。

參與者

1.Component

為組合中的對象聲明接口。

在適當(dāng)?shù)那闆r下,實現(xiàn)所有類共有接口的缺省行為。

聲明一個接口用于訪問和管理Component的子組件。

(可選)在遞歸結(jié)構(gòu)中定義一個接口,用于訪問一個父部件,并在合*的情況下實現(xiàn)它。

2.Leaf

在組合中表示葉節(jié)點對象,葉節(jié)點沒有子節(jié)點。

在組合中定義節(jié)點對象的行為。

3.Compos*te

定義有子部件的*些部件的行為。

存儲子部件。

在Component接口中實現(xiàn)與子部件有*的操作。

4.Client

通過Component接*操縱組合部件的對象。

類圖

例子Component

p*blicabstractclassEmployer{

privateStringname;

publicvoidsetName(Stringname){

=*ame;

}

publicStringgetName(){

return;

}

publicabstractvoidadd(Employeremployer);

publicabstractvoiddelete(Employeremployer);

publicListemployers;

publicvoidprintInfo(){

System.out.println(name);

}

*ublicListgetE*ployers(){

returnthis.employers;

}}Leaf

publicclassProgrammerextendsEmployer{

publicProgrammer(Stringname){

setNam*(name);

employers=null;//程序員,表示沒有下屬了

}

publicv*idadd(Employeremployer){

}

publicvoiddelete(Employeremployer){

}}

publicclassPro*ectAssistantextendsEmployer{

publicProjectAss*stant(Stringname){

setName(name);

employers=*ull;//項目助理,表示沒有下屬了

}

publicvoidadd(Employeremployer){

}

publicvoiddelet*(Employeremployer){

}}Composite

publicclassProject*anagerextendsE*ployer{

publicProjectManager(Stringname){

setName(name);

employers=newA*rayList();

}

publicvoidadd(Employeremployer){

employers.add(employer);

}

publicvoiddelete(Emplo*eremployer){

employers.remove(employer);

}}Clie*t

publ*cclassTest{

publicst*ticvoidmain(String[]args){

Employerpm=newProjectManager("項目經(jīng)理");

Emplo*erpa=newProjectAssistant("項目助理");

Employerprogra*mer1=newProgrammer("程序員一");

Employerprogrammer2=newProgrammer("程序員二");

pm.add(pa);//為項目經(jīng)理添加項目助理

pm.add(programmer2);//*項目經(jīng)理*加程序員

Listems=pm.getEm*loyers();

for(Employerem:ems){

System.out.println(em.getNam*());

}

*}result

項目助理程序員二1.2.4裝飾模式

動態(tài)地給一個對象添加一些額外的職責(zé)。就增加功能來說,Decorator模*相比生成子類更為*活。

適用性

1.在不影響其他*象的情況下,以動態(tài)、透明的方式給單個對象添加職責(zé)。

2.處理那些可以撤消的職責(zé)。

3.當(dāng)不能采用生成子類的方法進行擴充時。

參與者

1.Component

定義一個對象接口,可以給這些對象動態(tài)地添加職責(zé)。

2.ConcreteComponent

定義一個對象,可以給這個對象添加一些職責(zé)。

3.Decorator

維持一個指向Component對象的指針,并定義一個與Component接口一致的接口。

4.ConcreteDecorator

向組件添加職責(zé)。

類圖

例子Component

publicinterfacePerson{

voideat();}ConcreteComponent

*ublicclassM*nimplementsPerson{

publicvoideat(){

System.out.println("男人在吃");

*}Decorator

publicabstrac*classDecoratorimplementsPerso*{

protectedPersonperson*

publicvoidsetPerson(Personperson){

this.person=person;

}

publicvoideat(){

person.eat();

}}ConcreteDec*rator

publi*classManDecoratorAextendsDecorator{

publicvoideat(){

super.eat();

reEat();

Sy*tem.out.println("ManDecoratorA類");

}

publicvoidreEat(){

System.out.println("再吃一頓飯");

*}

publicclassManDecoratorBextendsDecorator*

publicvoideat(){

super.eat();

Syst*m.out.println("===============");

System.out.println("ManDecoratorB類");

}}Test

publicclassTest{

publicst*ticvoidmain(Strin*[]args){

Manman=newMan();

ManDecoratorAmd1=newManDecoratorA();

ManDecoratorBmd2=n*wManDecoratorB();

md1.setPerson(man);

md2.setPerson(md1);

md2.eat();

}}result

男人在吃再吃一頓飯ManDecoratorA類===============ManDecoratorB類1.2.5外觀模式

為子系統(tǒng)中的一組接口提供一個一致的界面,F(xiàn)acade模式定義了一個高層接口,這個接口使得這*子系統(tǒng)更加容易使用。

適用性

1.當(dāng)你要為一個*雜子系統(tǒng)提供一個簡單接口時。子系統(tǒng)往往因為不斷演化而變得越來越

復(fù)雜。大多數(shù)模式使用時都會產(chǎn)生更多更小的類。這使得子系統(tǒng)更具可重用性,也更容

易對子系統(tǒng)進行定制,但這也給*些不需要定制子系統(tǒng)的用戶帶來一些使用上的困難。

Fa*ade可以提供一個簡單的缺省視圖,這一視圖對大多數(shù)用戶來說已經(jīng)足*,而那些需

要更多的可定制性的用戶可以越過facade層。

2.客戶程序與抽象類的實現(xiàn)部分之間存在著很大的依賴性。引入facade將這個子系統(tǒng)與客

戶以及其他的子系統(tǒng)分離,可以提高子系統(tǒng)的獨立性和可移植性。

3.當(dāng)你需要構(gòu)建一個層次結(jié)構(gòu)的子系統(tǒng)時,使用facade模式定義子系統(tǒng)中每層的入口點。

如果子系統(tǒng)之間是相互依賴的,你可以讓它們僅通過facade進行通訊,從而簡化了它們

之間的依賴關(guān)系。

參與者

1.Facade

知道哪些子系統(tǒng)類負責(zé)處理請求。

將客戶的請求代理給適當(dāng)?shù)淖酉到y(tǒng)對象。

2.Subsystemclasses

實現(xiàn)子系統(tǒng)的功能。

處理由Facade對象指派的任務(wù)。

沒有facade的任何相關(guān)信息;即沒有指向*acade的指針。

類圖

例子Facade

publi*classFacade{

ServiceAsa;

ServiceBsb;

ServiceCsc;

publicFacade(){

sa=newS*rviceAImpl();

sb=new*erviceBImpl();

sc=newServiceCImpl();

}

publicvoidmethodA(){

sa.methodA();

sb.methodB();

}

publi*voidmethodB(){

s*.methodB();

sc.methodC();

}

publicvoidmethodC(){

sc.methodC();

sa.methodA();

}}Subsystemclasse*

public*lassServiceAImplimplementsServiceA{

publicvoidmethodA(){

System.out.println("這是服務(wù)A");

}}

publicclassServiceBImplimplementsServiceB{

publicvoidmethodB(){

System.out.println("這是服務(wù)B");

*}

publicclassServiceCImplimplementsServiceC{

publicvoidmethodC(){

System.out.println("這是服*C");

}}Test

publicclassTest{

publicstaticvoi*main(String[]args){

ServiceAsa=newServiceAImpl();

Ser*iceBsb=newServiceBImpl();

sa.metho*A();

sb.methodB();

System.out.println("========");

//facade

Facadefacade=newFacade();

facade.methodA();

facade.methodB();

}}resu*t

這是服務(wù)A這是*務(wù)B========這是服務(wù)A這是服務(wù)B這是服務(wù)B這是服務(wù)C1.2.6享元模式

運用共享技術(shù)有效地支持大量細粒度的對象。

適用性

當(dāng)都具備下列情況時,使用Flyweight模式:

1.一個應(yīng)用程序使用了大量的*象。

2.完全由于使用大量的對象,造成很大的存儲開銷。

3.對象*大多數(shù)狀態(tài)都可變?yōu)橥獠繝顟B(tài)。

4.如果刪除對象的外部狀態(tài),那么可以*相對較少的共享對象取代很多組對象。

5.應(yīng)用程序不依賴于對象標(biāo)識。由于Flyweight對象可以被共享,對于*念上明顯有別的對象,標(biāo)識測試將返回真值。

參與者

1.Flyweight

描述一個接口,通過這個接口flyweight可以接受并作用于外部狀態(tài)。

2.ConcreteFlyweight

實現(xiàn)Flyweight接口,并為內(nèi)部狀態(tài)(如果有的話)增加存儲空間。

Concrete*lyweight對象必須是可共享的。它所存儲的狀態(tài)必須是內(nèi)部的;即,它必須獨立于ConcreteFlyweight對象的場景。

3.UnsharedConcreteFlyweigh*

并非所有的Flywe*ght子類都需要被共享。Flyweight接口使共享成為可能,但它并不強制共*。

在Flyweight對象結(jié)構(gòu)的某些層次,UnsharedConcreteFlyweight對象通常將ConcreteFlyweight對象作為子節(jié)點。

4.Flyweigh*Factory

創(chuàng)建并管理flywe*ght對象。

確保合理地共享flyweight。當(dāng)用戶請求一個flywei*ht時,F(xiàn)l*weightFactory對象提供一個已創(chuàng)建的實例或者創(chuàng)建一個(如果不存在的話)。

類*

例子Flyweight

publicint*rfaceFlyweight{

voida*tion(intarg);}ConcreteFlyweight

publicclassFlyweightImplimplementsFlyweight{

publicvoidaction(intarg){

//T*DOAuto-genera*edmethodstub

System.out.println(*參數(shù)值:"+arg);

}}FlyweightFactory

publicclassFlyweigh*Factory{

privatestaticMapflyweights=newHashMap();

publicFlyweightF*ctory(Stringarg){

flyweights.put(arg,newFlyweightImpl());

}

publicstaticFlyweightgetFly*eight(Stringkey){

if(flyweights.get(key)==null){

flyweights.p*t(key,newFlyweightImpl());

}

returnflyweights.get(key);

}

publicstaticintg*tSize(){

retu*nflyweights.size();

}}Test

publicclassTest{

publicstaticv*idmain(String[]args){

//TODOAuto-generatedmethodstub

Flyweightfly1=Flyw*ightFact*ry.getFlyweight(*a");

fly1.action(1);

Flyweightfly*=FlyweightFactory.getF*yweight("a");

System.out.println(fly1==fly2);

Flyweightfl*3=FlyweightFactory.getFlywei*ht("b");

fly3.action(2);

Flyweightfly4=Flyweigh*Factory.getF*yweight("c");

fly4.action(3);

Flyweigh*fly5=FlyweightFactory.getFlyweight("d");

fly4.action(4);

System.out.println(FlyweightFactory.getSize())*

}}result

參數(shù)值:1true參數(shù)值:2*數(shù)值:3參數(shù)值:441.2.7代理模式

為其他對象提供一種代理以控制對這個對象的訪問。

適用性

1.遠程代理(RemoteProxy)為一個對象在不同的地址空間提供局部代表。

2.虛*理(VirtualProxy)根據(jù)需*創(chuàng)建開銷很大的對象。

3.保護代理(ProtectionProxy)控制對原始對象的訪問。

4.智能指引(SmartReference)取代了簡單的指針,它在訪問對象時執(zhí)行一些附加操作。

參與者

1.Proxy

保存一個引用使得代理可以訪問實體。若RealSubject和Subject的接口相同,Proxy會引用Subject。

*供一個與Subject的接口相同的接口,這樣代理就可以用來替代實體。

控制對實體的*取,并可能負責(zé)創(chuàng)建和刪除它。

其他功能依賴于*理的類型:

2.RemoteProxy負責(zé)對請求及其參數(shù)進行編碼,并向不同地址空間中的實體發(fā)送已編碼的請求。

*.VirtualProxy可以緩存實體的附加信息,以便延遲對它的訪問。

4.ProtectionProxy檢查調(diào)用者是*具有實現(xiàn)一個請求所必需的訪問權(quán)限。

5.Subjec*

定義RealSubject和Proxy的共用接口,這樣就在任何使用RealSubject的地方都*以使用Proxy。

6.RealSubject

*義Proxy所代表的實體。

類圖

例子Proxy

publicclassProxyObjectimplementsObject{

Objec*obj;

publicProxyObject(){

System.out.println("這是代理類");

o*j=newObjectImpl();

}

publicvoidac*ion(){

System.out.p*intln("代理開始");

obj.action*);

System.out.println(*代理結(jié)束");

}}Subject

publicinterfaceObje*t{

voidaction();}RealSubject

publicclassObjectImplimplementsObject{

pu*licvoidaction(){

System.out.println("========");

System.out.println("========");

System.out.pr*ntln("這是被代理的類");

System.out.println("========");

System.out.println("========");

}}Test

publicclassTest{

publi*staticvoidmain(){

Objectob*=newProxyObject();

obj.action();

*}result

這是代理類代理開始=========*======這是被代理的類==============*=代理結(jié)束1.3行為型模式ChainofResponsibility(責(zé)任鏈模式)Command(命令模式)Interpreter(解釋器模式)Iterator(迭代器*式)Mediator(中介者模式)Memento(備忘錄模式)Observer(觀察者模式)State(狀*模式)Strategy(策略模式)TemplateMethod(模板方法)Vis*tor(訪問者模式)1.3.1責(zé)任鏈模式

使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對象連成一*鏈,

并*著這條鏈傳遞該請求,直到有一個對象處理它為止。

這一模式的想法是,給多個對象處理一個請求的機會,從而解耦發(fā)送者和接受者.

適用性

1.有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定。

2.你*在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。

3.可處理一個請求的對象集合應(yīng)被動態(tài)指定。

參與者

1.Handler

定義一個處理請求的接口。

(可選)實現(xiàn)后繼鏈。

2.ConcreteHandler

處理它所負責(zé)的請*。

可訪問它的后繼者。

如果可處理該*求,就處理*;否則將該請求轉(zhuǎn)發(fā)給它的后繼者。

3.Client

向鏈上的具體處理者(ConcreteHandler)對象提交請求。

類圖

例子Hand*er

publicinterfaceRequestHandle{

voidhandleRequest(R*questrequest);}ConcreteHandler

publicclassHRRequestHandleimplementsRequestHandle{

publicvoidhandleRequest(Requestrequest){

if(requestinstanceofDimissionRequest){

System.out.println("要離職,人事審批!");

}

System.out.println("請求完*");

}}

publicclassPMRequestHandleimplementsRequestHandle{

Req*estHandlerh;

publicPMRequestHandle(RequestHandle*h){

this.rh=rh;

}

publicvoidhandle*equest(Requestrequest){

if(requestinstanceofAddMoneyRequest){

System.out.println("要加薪,項目經(jīng)理審批!*);

}else{

rh.handleRequest(request);

}

}}

publicclassTLRequestHandleimplementsRequestHandle{

RequestHandlerh;

publicTLRequestHandle(RequestHand*erh){

this.rh=rh;

}

publicvoidhandleRequest(Requestrequest){

if(requestinstanceofLeaveRe*uest){

System.ou*.println("要請假,項目組長審批!");

}else{

rh.handleRequest(request);

}

}}Client

public*lassTest{

publicstaticv*idmain(String[]args){

RequestHa*dlehr=*ewHRRequ*stHandle();

Requ*stHandlepm=newP*RequestHandle(hr);

RequestHandletl=newTLRequestHandle(pm);

//teamleader處理離職請求

Requestrequest=newDimissionRequest()*

tl.handleRequest(request);

System.out.println("===========");

//teamleader處理加薪請求

request=newAddMoneyRequest();

tl.handleRequ*st(request);

System.out.println("========");

//項目經(jīng)理上理辭職請求

requ*st=ne*Dimissio*Request();

pm.handleRequest(request);

}}result

要離職,人事審批!請求完畢=======*===要加薪,項目經(jīng)理審批!========要離職,人事審批!請求完畢1.3.2命令模式

將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,以及支持可撤消的*作。

適用性

1.抽象出待執(zhí)行的動作以參數(shù)化某對象。

2.在不同的時刻指定、排列和執(zhí)行請求。

3.支持取消操作。

4.支持修改日志,這樣當(dāng)系統(tǒng)崩潰時,這*修改可以被重做一遍。

5.用構(gòu)建在原語操作上的高層操作構(gòu)造一個系統(tǒng)。

參與者

1.Comma*d

聲明執(zhí)行操作的接口。

2.ConcreteCommand

將一個接收者對象綁定于一個動作。

調(diào)用接收者相應(yīng)的操作,以實現(xiàn)Execute。

3.Client

創(chuàng)建一個具體命令對象并設(shè)定它的接收者。

4.Invoker

要求該命令執(zhí)行這個請求。

5.Recei*er

知道如何實*與執(zhí)行一個請求相關(guān)的操作。任何類都可能作為一個接收者。

類圖

例子Command

publicabstractclass*ommand{

protecte*Receiverreceiver;

publicCommand(Receiverre*eiver){

this.receiver=receiver;

}

publicabstract*oidexecute();}ConcreteCommand

publicclassCommandImplextendsComman*{

publicCommandImpl(Receiv*rreceiver){

super(receiver);

}

pu*licvoid*xecute*){

receiver.request();

}}Invoker

publiccl*ssInvoker{

privateCommandcommand;

pub*icvoidsetCommand(Commandc*mmand){

mand=command;

}

publicvoidexecute*){

command.execute();

}}Receiver

publicclassReceiver{

publicvoidreceive(){

S*stem.out.println("ThisisReceiveclass!");

}}Test

publ*cclassTest{

pub*icstaticvoidmain*String[]args){

R*ceiverrec=newReceiver();

Commandcmd=n*wCommandImpl(rec);

Invokeri=newInvoker();

i.setCom*and(cmd);

i.execut*();

}}result

ThisisReceiveclass!1.3.3解釋器模式

給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。

適用性

當(dāng)有一個語言需要解釋執(zhí)行,并且你可將該語言中的句子表示為一個抽象語法樹時,可使

用解釋器模式。而當(dāng)存在*下情況時該模式效果最好:

1.該文法簡單對于復(fù)雜的文法,文法的*層次變得龐大而無法管理。

2.效率不是一個關(guān)鍵問題最高效的解釋器通常不是通過直接解釋語法分析樹實現(xiàn)的,而是首先將它們轉(zhuǎn)換成另一種形式。

參與者

1.AbstractExpression(抽象表達式)

聲明一個抽象的解釋操作,這個接口為抽象語法樹中所有的節(jié)點所共享。

2.TerminalExpression(終結(jié)符表達式)

實現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作。

一個句子中的每個終結(jié)符需要該類的一個實例。

3.N*nterminalExpression(非終結(jié)符表達式)

為文法中的非終結(jié)符實現(xiàn)解釋(Interpret)操作。

4.Context(上下文)

包含解釋器之外的一些全局信息。

5.Client(客戶)

構(gòu)建(或被給定)表示該文法定義的語言中*個特定的句子的抽象*法樹。

該抽象語法樹由NonterminalExpression和TerminalExpression的實例裝配而成。

調(diào)用解*操作。

類圖

例子AbstractExpression

pu*licabstractclassExpression{

abstractvoidinterpret(Contextctx);}Expression

publicclassAdvanceExpressio*extendsExpression{

voidinterpr*t(Contextctx){

System.out.println("這是高級解析器!");

}}

publicclassSimpleExpressionextendsExpressio*{

voidinterpret(*ontextctx){

System.out.pri*tln("這是普通解析器!");

}}Context

publicclassCo*text{

privateS*ringcontent;

*rivateListlist=newArrayList();

溫馨提示

  • 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. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論