版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025宅基地轉(zhuǎn)讓合同 標(biāo)準(zhǔn)版模板全
- 小學(xué)三年級描寫同學(xué)的作文300字6篇
- 自強自立主題演講稿(匯編7篇)
- 個人工作總結(jié)與參考計劃參考范文
- 大學(xué)工作計劃四篇
- 陜西供排水項目可行性研究報告
- 普通員工辭職報告14篇
- 城鄉(xiāng)電網(wǎng)項目立項報告
- 個人年終述職報告怎么寫
- xx市天然氣管網(wǎng)及儲氣設(shè)施項目可行性研究報告
- 2024年安徽安慶宜秀區(qū)國企業(yè)招聘易考易錯模擬試題(共500題)試卷后附參考答案
- 替莫唑胺在小細胞肺癌中的應(yīng)用
- 不動產(chǎn)登記申請表
- 2024年中國中鐵十局招聘高頻難、易錯點500題模擬試題附帶答案詳解
- 第一、二單元語文園地鞏固練習(xí)-2024-2025學(xué)年語文六年級上冊統(tǒng)編版
- 2024年P(guān)URL系列反應(yīng)型皮革用聚氨酯乳液項目合作計劃書
- 巨量-營銷科學(xué)(初級)認(rèn)證培訓(xùn)考試題庫(含答案)
- 2024-2030年中國城市更新行業(yè)市場深度分析及前景趨勢與投資戰(zhàn)略研究報告
- GB/T 44328-2024七氟異丁腈
- 生態(tài)環(huán)境保護課件
- 戶外徒步活動策劃方案(共5篇)
評論
0/150
提交評論