《軟件工程》11-補充-設計模式_第1頁
《軟件工程》11-補充-設計模式_第2頁
《軟件工程》11-補充-設計模式_第3頁
《軟件工程》11-補充-設計模式_第4頁
《軟件工程》11-補充-設計模式_第5頁
已閱讀5頁,還剩60頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

設計模式軟件設計是一門藝術,是對“變化”的辯證處理:發現變化,隔離變化,以不變應萬變。設計模式分類創建模式結構模式行為模式優點面向接口編程降低耦合性增加靈活性設計模式之Factory-工廠模式客戶類和工廠類分開。客戶任何時候需要某種產品,只需向工廠請求即可。客戶無須修改就可以接納新產品。缺點是當產品修改時,工廠類也要做相應的修改。設計模式之Factory-工廠模式publicclassFactory{

publicstaticSamplecreator(intwhich){

//產生Sample一般可使用動態類

//裝載裝入類。

if(which==1)

returnnewSampleA();

elseif(which==2)

returnnewSampleB();

}}FACTORYMETHOD-工廠方法定義一個用于創建對象的接口,讓子類決定實例化哪一個類。FactoryMethod使一個類的實例化延遲到其子類。

publicabstractclassCarFactory{

publicabstractCarcreator();}publicclassVW1FactoryextendsCarFactory{ publicCarcreator(){

.........

returnnewJetta;

}}publicclassVW2FactoryextendsCarFactory{ publicCarcreator(){

......

returnnewPolo; }}AbstractFactory–抽象工廠提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。publicabstractclassCarFactory{

publicabstractCarcreator();

publicabstractTruckcreator(Strings);}publicclassVW1FactoryextendsCarFactory{

publicCarcreator(){

.........

returnnewJetta;

}

publicTruckcreator(Strings){

.........

returnnewBigTruck;

}}publicclassVM2extendsCarFactory{

publicCarcreator(){

......

returnnewPolo; }

publicTruckcreator(Strings){

......

returnnewLargeTruck;

}}Builder-建造模式將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

建造模式可以強制實行一種分步驟進行的建造過程。publicinterfaceBuilder{

//創建部件A:比如汽車車輪

voidbuildPartA();

//創建部件B:比如方向盤

voidbuildPartB();

//創建部件C:比如發動機

voidbuildPartC();

//返回最終組裝產品成果(返回最后裝配好的汽車)

//成品的組裝過程不在這里進行,而是轉移到下面的Director中進行。

//從而實現過程與部件的解耦。

ProductgetResult();}publicclassDirector{

privateBuilderbuilder; publicDirector(Builderbuilder){

this.builder=builder;

}

//將partA,partB,partC最后組成復雜物件

//汽車的組裝過程

publicvoidconstruct(){

builder.buildPartA();

builder.buildPartB();

builder.buildPartC();

}}PROTOTYPE-原型模式用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。缺點是每一個類都必須配備一個克隆方法。其實是將product和factory功能合二為一了。publicabstractclassAbstractSpoonimplementsCloneable

{

StringspoonName;

publicvoidsetSpoonName(String

spoonName){this.spoonName=spoonName;}

publicStringgetSpoonName(){returnthis.spoonName;}

publicObjectclone()

{

Objectobject=null;

try{

object=super.clone();

}catch(CloneNotSupportedExceptionexception){

System.err.println("AbstractSpoonisnotCloneable");

}

returnobject;

}

}

publicclassSoupSpoonextendsAbstractSpoon

{

publicSoupSpoon()

{

setSpoonName("SoupSpoon");

}

}publicclassSaladSpoonextendsAbstractSpoon

{

publicSaladSpoon()

{

setSpoonName("SaladSpoon");

}

}設計模式之Singleton-單例模式保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。解決的主要是性能問題,而非耦合(變化)的問題。publicclassSingleton{

privatestaticSingletoninstance=null;

publicstaticsynchronizedSingletongetInstance(){

//這個方法不用每次都進行生成對象,

//只是第一次使用時生成實例,提高了效率!

if(instance==null)

instance=newSingleton();

returninstance;

}}

Adapter-適配器把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口原因不匹配而無法一起工作的兩個類能夠一起工作。適配類可以根據參數返還一個合適的實例給客戶端。publicinterfaceIRoundPeg{

publicvoidinsertIntoHole(String

msg);}publicinterfaceISquarePeg{

publicvoidinsert(String

str);}publicclassPegAdapterimplementsIRoundPeg,ISquarePeg{

privateRoundPeg

roundPeg;

privateSquarePeg

squarePeg;

//構造方法

publicPegAdapter(RoundPeg

peg){this.roundPeg=peg;}//構造方法

publicPegAdapter(SquarePeg

peg){this.squarePeg=peg;}

publicvoidinsert(String

str){

if(roundPeg!=NULL)roundPeg.insertIntoHole(str);

if(squarePeg!=NULL)squarePeg.insert(str); }

publicvoidinsertIntoHole(String

str){ …

SquarePeg.insert(str);}}Bridge-橋梁模式將抽象部分與它的實現部分(行為)分離,使它們都可以獨立地變化。解決2個方面的變化問題:抽象與實現(行為)。即一個類中多個方向的變化問題。publicabstractclassCoffee{

CoffeeImp

coffeeImp;

publicvoidsetCoffeeImp(){

this.CoffeeImp=CoffeeImpSingleton.getTheCoffeImp();

}

publicCoffeeImp

getCoffeeImp(){returnthis.CoffeeImp;}

publicabstractvoidpourCoffee();}publicabstractclassCoffeeImp{ publicabstractvoidpourCoffeeImp();}//bridgepublicclassCoffeeImpSingleton

{privatestaticCoffeeImp

coffeeImp;

publicCoffeeImpSingleton(CoffeeImp

coffeeImpIn)

{this.coffeeImp=coffeeImpIn;}

publicstaticCoffeeImp

getTheCoffeeImp()

{

returncoffeeImp;

}

}//中杯publicclassMediumCoffeeextendsCoffee{

publicMediumCoffee(){setCoffeeImp();}

publicvoidpourCoffee()

{

CoffeeImp

coffeeImp=this.getCoffeeImp();

//我們以重復次數來說明是沖中杯還是大杯,重復2次是中杯

for(inti=0;i<2;i++)

{

coffeeImp.pourCoffeeImp();

}

}}//大杯publicclassSuperSizeCoffeeextendsCoffee{

publicSuperSizeCoffee(){setCoffeeImp();}

publicvoidpourCoffee()

{

CoffeeImp

coffeeImp=this.getCoffeeImp();

//我們以重復次數來說明是沖中杯還是大杯,重復5次是大杯

for(inti=0;i<5;i++)

{

coffeeImp.pourCoffeeImp();

}

}}//加奶publicclassMilkCoffeeImpextendsCoffeeImp{

MilkCoffeeImp(){}

publicvoidpourCoffeeImp()

{

System.out.println("加了美味的牛奶");

}}//不加奶publicclassFragrantCoffeeImpextendsCoffeeImp{

FragrantCoffeeImp(){}

publicvoidpourCoffeeImp()

{

System.out.println("什么也沒加,清香");

}}//拿出牛奶CoffeeImpSingleton

coffeeImpSingleton=newCoffeeImpSingleton(new

MilkCoffeeImp());//中杯加奶MediumCoffee

mediumCoffee=newMediumCoffee();mediumCoffee.pourCoffee();//大杯加奶SuperSizeCoffee

superSizeCoffee=newSuperSizeCoffee();superSizeCoffee.pourCoffee();組合由于繼承原則面向接口編程原則單一職責原則Liskov替換原則等等Composite-合成模式合成模式把部分與整體關系用樹結構表示。合成模式使得用戶對單對象和組合對象的使用具有一致性。publicabstractclassEquipment{

privateStringname;

//網絡價格

publicabstractdoublenetPrice();

//打折價格

publicabstractdoublediscountPrice();

//增加部件

publicboolean

add(Equipmentequipment){returnfalse;}

//刪除部件

publicboolean

remove(Equipmentequipment){returnfalse;}

//注意這里,提供一種用于訪問組合部件的方法。

publicIterator

iter(){returnnull;}

publicEquipment(finalStringname){=name;}}

publicclassDiskextendsEquipmentabstractclassCompositeEquipmentextendsEquipmentDECORATOR-裝飾模式一個類可能有些額外的責任(除了主體業務操作),如加密、緩存、壓縮等,這些可能只是輔助主體業務的附著,并不嚴格按照維度變化。裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案,提供比繼承更多的靈活性。動態給一個對象增加功能,這些功能可以再動態的撤消。增加由一些基本功能的排列組合而產生的非常大量的功能。既繼承又組合,實際上是將Bridge中的抽象和實現合二為一了,是其特殊形式。publicinterfaceWork{

publicvoidinsert();}publicclassSquarePegimplementsWork{

publicvoidinsert(){

System.out.println(“方形樁插入");

}}publicclassDecoratorimplementsWork{

privateWorkwork;

//額外增加的功能打包在List中

privateArrayListothers=newArrayList();

//在構造器中使用組合new方式,引入Work;

publicDecorator(Workwork){

this.work=work;

others.add(“挖坑");

others.add(“釘木板");

}

publicvoidinsert(){

newMethod();

}

//新方法中在insert之前增加其他方法,這里次序先后是用戶靈活指定的

publicvoidnewMethod(){

otherMethod();

work.insert();

}

publicvoidotherMethod(){

ListIterator

listIterator=others.listIterator();

while(listIterator.hasNext())

{

System.out.println(((String)(listIterator.next()))+“正在進行");

}

}}Facade–外觀模式外部與一個子系統的通信必須通過一個統一的門面對象進行。門面模式提供一個高層次的接口,使得子系統更易于使用。每一個子系統只有一個門面類,而且此門面類只有一個實例,也就是說它是一個單例模式。但整個系統可以有多個門面類。JDBCFLYWEIGHT

-享元模式享元模式以共享的方式高效的支持大量的細粒度對象。采用類似于Hash表的方式,共享的思想。客戶端不可以直接創建被共享的對象,而應當使用一個工廠對象負責創建被共享的對象。享元模式大幅度的降低內存中對象的數量,主要解決OO性能問題。publicclassCD{

privateStringtitle;

privateintyear;

privateArtistartist;

publicStringgetTitle(){returntitle;}

publicint

getYear(){returnyear;}

publicArtistgetArtist(){returnartist;}

publicvoidsetTitle(Stringt){title=t;}

publicvoidsetYear(inty){year=y;}

publicvoidsetArtist(Artista){artist=a;}}publicclassArtist{

//內部狀態

privateStringname;

//notethatArtistisimmutable.

StringgetName(){returnname;}

Artist(Stringn){name=n;}}publicclassArtistFactory{

Hashtablepool=newHashtable();

ArtistgetArtist(Stringkey){

Artistresult; result=(Artist)pool.get(key); //產生新的Artist

if(result==null){

result=newArtist(key);

pool.put(key,result);

}

returnresult; }}PROXY-代理模式代理模式給某一個對象提供一個代理對象,并由代理對象控制對源對象的引用。代理就是一個人或一個機構代表另一個人或者一個機構采取行動。代理對象可以在客戶和目標對象直接起到中介的作用。客戶端分辨不出代理主題對象與真實主題對象。代理模式可以并不知道真正的被代理對象,而僅僅持有一個被代理對象的接口,這時候代理對象不能夠創建被代理對象,被代理對象必須有系統的其他角色代為創建并傳入。代理者對被代理者的功能進行擴展(OCP)。ChainofResponsibility–職責鏈

很多對象由每一個對象對其下家的引用而接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。客戶并不知道鏈上的哪一個對象最終處理這個請求,系統可以在不影響客戶端的情況下動態的重新組織鏈和分配責任。處理者有兩個選擇:承擔責任或者把責任推給下家。一個請求可以最終不被任何接收端對象所接受。publicinterfaceHandler{

publicvoidhandleRequest(Requestrequest);}

publicclassRequest{

privateStringtype;

publicRequest(String

type){this.type=type;}

publicStringgetType(){returntype;}

publicvoidexecute(){

//request真正具體行為代碼

}}publicclassConcreteHandlerimplementsHandler{

privateHandlersuccessor;

publicConcreteHandler(Handlersuccessor){

this.successor=successor;

}

publicvoidhandleRequest(Requestrequest){

if(requestinstanceof

HelpRequest){

//這里是處理Help的具體代碼

}elseif(requestinstanceof

PrintRequst){

request.execute();

}else{

//傳送到下一個

successor.handle(request); } }}COMMAND-命令模式

命令模式把一個請求或者操作封裝到一個對象中。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。命令模式允許請求的一方和發送的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否執行,何時被執行以及是怎么被執行的。系統支持命令的撤消。解耦服務的調用者與服務提供者,請求方只知道execute即可。publicinterfaceCommand{

publicabstractvoidexecute();}publicclassproducer{

publicstaticListproduceRequests(){

Listqueue=newArrayList();

queue.add(newDomesticEngineer());

queue.add(newPolitician());

queue.add(newProgrammer());

returnqueue;

}}publicclassTestCommand{

publicstaticvoidmain(String[]args){

Listqueue=PduceRequests();

for(Iteratorit=queue.iterator();it.hasNext();) //取出List中的內容,其他特征不能確定,只能保證一個特征是100%正確,

//他們至少是界面Command的“兒子”。所以強制轉換類型為Command

((Command)it.next()).execute();

}}INTERPRETER-解釋器模式給定一個語言后,解釋器模式可以定義出其文法的一種表示,并同時提供一個解釋器。客戶端可以使用這個解釋器來解釋這個語言中的句子。解釋器模式將描述怎樣在有了一個簡單的文法后,使用模式設計解釋這些語句。在解釋器模式里面提到的語言是指任何解釋器對象能夠解釋的任何組合。在解釋器模式中需要定義一個代表文法的命令類的等級結構,也就是一系列的組合規則。每一個命令對象都有一個解釋方法,代表對命令對象的解釋。命令對象的等級結構中的對象的任何排列組合都是一個語言。ITERATOR-迭代子模式迭代子模式可以順序訪問一個聚集中的元素而不必暴露聚集的內部表象。多個對象聚在一起形成的總體稱之為聚集,聚集對象是能夠包容一組對象的容器對象。迭代子模式將迭代邏輯封裝到一個獨立的子對象中,從而與聚集本身隔開。迭代子模式簡化了聚集的界面。每一個聚集對象都可以有一個或一個以上的迭代子對象,每一個迭代子的迭代狀態可以是彼此獨立的。迭代算法可以獨立于聚集角色變化。//遍歷Collection中內容publicclassTestCommand{

publicstaticvoidmain(String[]args){

Listqueue=PduceRequests();

for(Iteratorit=queue.iterator();it.hasNext();)

((Command)it.next()).execute();

}}MEDIATOR-調停者模式調停者模式包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用。從而使他們可以松散偶合。當某些對象之間的作用發生改變時,不會立即影響其他的一些對象之間的作用。保證這些作用可以彼此獨立的變化。調停者模式將多對多的相互作用轉化為一對多的相互作用。調停者模式將對象的行為和協作抽象化,把對象在小尺度的行為上與其他對象的相互作用分開處理。架構級模式,Fa?ade解決子系統間的問題,Mediator解決子系統內(對象間)復雜問題。publicinterfaceMediator{}publicclassConcreteMediatorimplementsMediator{

//假設當前有兩個成員

privateConcreteColleague1colleague1=newConcreteColleague1();

privateConcreteColleague2colleague2=newConcreteColleague2();

...}

publicclassColleague{

privateMediatormediator;

publicMediatorgetMediator(){

returnmediator; }

publicvoidsetMediator(Mediatormediator){

this.mediator=mediator; }}publicclassConcreteColleague1{}publicclassConcreteColleague2{}MEMENTO-備忘錄模式備忘錄對象是一個用來存儲另外一個對象內部狀態的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態捉住,并外部化,存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態。publicclassOriginator{ privateintnumber; privateFilefile=null;

publicOriginator(){}

//創建一個Memento publicMementogetMemento(){

returnnewMemento(this); }

//恢復到原始值

publicvoidsetMemento(Mementom){

number=m.number;

file=m.file; }}privateclassMementoimplementsjava.io.Serializable{

privateintnumber;

privateFilefile=null;

publicMemento(Originatoro){

number=o.number;

file=o.file;

}}OBSERVER-觀察者模式觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。publicclassproductextendsObservable{ privateStringname;

privatefloatprice;

publicStringgetName(){returnname;}

publicvoidsetName(){

=name;

//設置變化點

setChanged();

notifyObservers(name); }

}publicclassNameObserverimplementsObserver{

privateStringname=null;

publicvoidupdate(Observable

obj,Object

arg){

if(arg

instanceofString){

name=(String)arg;

//產品名稱改變值在name中

System.out.println("NameObserver:namechangedto"+name);

}

}}STATE-狀態模式狀態模式允許一個對象在其內部狀態改變的時候改變行為。這個對象看上去象是改變了它的類一樣。狀態模式把所研究的對象的行為包裝在不同的狀態對象里,每一個狀態對象都屬于一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候,其行為也隨之改變。狀態模式需要對每一個系統可能取得的狀態創立一個狀態類的子類。當系統的狀態變化時,系統便改變所選的子類。管理類在不同狀態下的行為。publicclassBlueStateextendsState{ publicvoidhandlepush(Contextc){

//根據push方法“如果是blue狀態的切換到green”;

c.setState(new

GreenState());

}

publicvoidhandlepull(Contextc){

//根據pull方法“如果是blue狀態的切換到red”;

c.setState(new

RedState()); }

publicabstractvoidgetcolor(){return(Color.blue);}}publicclassContext{ privateSatestate=null;//將原來的Colorstate改成了新建的Statestate; //setState是用來改變state的狀態,使用setState實現狀態切換

pulicvoidsetState(Statestate){

this.state=state; } publicvoidpush(){

//狀態切換細節,本例是顏色變化,封裝在子類handlepush中,此處無需關心

state.handlepush(this);

//因為sample要使用state中的一個切換結果,使用getColor()

Samplesample=newSample(state.getColor());

sample.operate(); } publicvoidpull(){

state.handlepull(this);

Sample2sample2=newSample2(state.getColor());

sample2.operate();

}}STRATEGY-策略模式策略模式針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發生變化。策略模式把行為和環境分開。環境類負責維持和查詢行為類,各種算法在具體的策略類中提供。由于算法和環境獨立開來,算法的增減,修改都不會影響到環境和客戶端。與State較象,類中封裝算法,定義一組算法。publicabstractclassRepTempRule{

protectedStringoldString="";

publicvoidsetOldString(String

oldString){

this.oldString=oldString;

}

protectedStringnewString="";

publicStringgetNewString(){

returnnewString;

}

publicabstractvoidreplace()throwsException;}publicclasstest{ ...... publicvoidtestReplace(){

//使用第一套方案進行替換

RepTempRulerule=newRepTempRuleOne();

rule.setOldString(record);

rule.replace();

} .....}TE

溫馨提示

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

評論

0/150

提交評論