C#設(shè)計模式大全_第1頁
C#設(shè)計模式大全_第2頁
C#設(shè)計模式大全_第3頁
C#設(shè)計模式大全_第4頁
C#設(shè)計模式大全_第5頁
已閱讀5頁,還剩181頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

..C#設(shè)計模式〔14一、

C#面向?qū)ο蟪绦蛟O(shè)計復(fù)習(xí)5二、設(shè)計模式舉例5三、先有雞還是先有蛋?7四、大瓶子套小瓶子還是小瓶子套大瓶子?8五、

.net本質(zhì)9C#設(shè)計模式〔211一、"開放-封閉"原則<OCP>12二、里氏代換原則〔LSP12C#設(shè)計模式〔319三、依賴倒置原則<DIP>19四、接口隔離原則〔ISP20五、合成/聚合復(fù)用原則〔CARP21六、迪米特法則〔LoD22C#設(shè)計模式〔4-SimpleFactoryPattern24一、簡單工廠〔SimpleFactory模式24二、

SimpleFactory模式角色與結(jié)構(gòu):24三、程序舉例:25四、

SimpleFactory模式演化27五、優(yōu)點與缺點:29C#設(shè)計模式〔5-FactoryMethodPattern30一、工廠方法〔FactoryMethod模式30二、

FactoryMethod模式角色與結(jié)構(gòu):30三、程序舉例:31四、工廠方法模式與簡單工廠模式33五、

FactoryMethod模式演化34六、

FactoryMethod模式與其它模式的關(guān)系35七、另外一個例子35C#設(shè)計模式〔6-AbstractFactoryPattern38一、抽象工廠〔AbstractFactory模式38二、

AbstractFactory模式的結(jié)構(gòu):39三、程序舉例:41四、在什么情形下使用抽象工廠模式:44五、抽象工廠的起源45六、

AbstractFactory模式在實際系統(tǒng)中的實現(xiàn)46七、

"開放-封閉"原則50C#設(shè)計模式〔7-SingletonPattern50一、單例〔Singleton模式50二、

Singleton模式的結(jié)構(gòu):51三、程序舉例:51四、在什么情形下使用單例模式:52五、

Singleton模式在實際系統(tǒng)中的實現(xiàn)53六、

C#中的Singleton模式55C#設(shè)計模式〔8-BuilderPattern57一、建造者〔Builder模式57二、

Builder模式的結(jié)構(gòu):58三、程序舉例:58四、建造者模式的活動序列:62五、建造者模式的實現(xiàn):62六、建造者模式的演化68七、在什么情況下使用建造者模式69C#設(shè)計模式〔9-PrototypePattern70一、原型〔Prototype模式70二、

Prototype模式的結(jié)構(gòu):71三、程序舉例:71四、帶PrototypeManager的原型模式73五、淺拷貝與深拷貝77六、

Prototype模式的優(yōu)點與缺點79C#設(shè)計模式〔10-AdapterPattern80一、適配器〔Adapter模式80二、類的Adapter模式的結(jié)構(gòu):81三、類的Adapter模式示意性實現(xiàn):81四、對象的Adapter模式的結(jié)構(gòu):83五、對象的Adapter模式示意性實現(xiàn):84六、在什么情況下使用適配器模式85七、一個實際應(yīng)用Adapter模式的例子85八、關(guān)于Adapter模式的討論87C#設(shè)計模式〔11-CompositePattern88一、合成〔Composite模式88二、合成模式概述88三、安全式的合成模式的結(jié)構(gòu)90四、安全式的合成模式實現(xiàn)91五、透明式的合成模式結(jié)構(gòu)93六、透明式的合成模式實現(xiàn)94七、使用合成模式時考慮的幾個問題97八、和尚的故事98九、一個實際應(yīng)用Composite模式的例子98C#設(shè)計模式〔12-DecoratorPattern101一、裝飾〔Decorator模式101二、裝飾模式的結(jié)構(gòu)102三、裝飾模式示例性代碼103四、裝飾模式應(yīng)當在什么情況下使用106五、裝飾模式實際應(yīng)用的例子106六、使用裝飾模式的優(yōu)點和缺點110七、模式實現(xiàn)的討論111八、透明性的要求111九、裝飾模式在.NET中的應(yīng)用112C#設(shè)計模式〔13-ProxyPattern113一、代理〔Proxy模式113二、代理的種類114三、遠程代理的例子114四、代理模式的結(jié)構(gòu)115五、代理模式示例性代碼115六、高老莊悟空降八戒117七、不同類型的代理模式118八、代理模式實際應(yīng)用的例子119設(shè)計模式〔14-FlyweightPattern122一、享元〔Flyweight模式122二、單純享元模式的結(jié)構(gòu)122三、單純享元模式的示意性源代碼123四、復(fù)合享元模式的結(jié)構(gòu)125五、一個咖啡攤的例子127六、咖啡屋的例子130七、享元模式應(yīng)當在什么情況下使用133八、享元模式的優(yōu)點和缺點134設(shè)計模式〔15-FacadePattern134一、門面〔Facade模式134二、門面模式的結(jié)構(gòu)134三、門面模式的實現(xiàn)135四、在什么情況下使用門面模式135五、一個例子136六、使用門面模式的設(shè)計140設(shè)計模式〔16-BridgePattern144一、橋梁〔Bridge模式144二、橋梁模式的結(jié)構(gòu)145三、橋梁模式的示意性源代碼146四、調(diào)制解調(diào)器問題149五、另外一個實際應(yīng)用Bridge模式的例子153六、在什么情況下應(yīng)當使用橋梁模式158設(shè)計模式〔17-ChainofResponsibilityPattern158一、職責鏈〔ChainofResponsibility模式160二、責任鏈模式的結(jié)構(gòu)160三、責任鏈模式的示意性源代碼160四、純的與不純的責任鏈模式163五、責任鏈模式的實際應(yīng)用案例163六、責任鏈模式的實現(xiàn)168設(shè)計模式〔18-CommandPattern168一、命令〔Command模式168二、命令模式的結(jié)構(gòu)168三、命令模式的示意性源代碼169四、玉帝傳美猴王上天172五、命令模式的實現(xiàn)172六、命令模式的實際應(yīng)用案例173七、在什么情況下應(yīng)當使用命令模式177八、使用命令模式的優(yōu)點和缺點178設(shè)計模式〔19-ObserverPattern178一、觀察者〔Observer模式178二、觀察者模式的結(jié)構(gòu)179三、觀察者模式的示意性源代碼180四、

C#中的Delegate與Event183五、一個實際應(yīng)用觀察者模式的例子187六、觀察者模式的優(yōu)缺點191設(shè)計模式〔20-VisitorPattern192一、訪問者〔Visitor模式192二、訪問者模式的結(jié)構(gòu)193三、示意性源代碼194四、一個實際應(yīng)用Visitor模式的例子198五、在什么情況下應(yīng)當使用訪問者模式202六、使用訪問者模式的優(yōu)點和缺點203設(shè)計模式〔21-TemplateMethodPattern204一、模板方法〔TemplateMethod模式204二、模版方法模式的結(jié)構(gòu)204三、模板方法模式的示意性代碼205四、繼承作為復(fù)用的工具207五、一個實際應(yīng)用模板方法的例子208六、模版方法模式中的方法210七、重構(gòu)的原則211設(shè)計模式〔22-StrategyPattern211一、策略〔Strategy模式211二、策略模式的結(jié)構(gòu)212三、示意性源代碼212四、何時使用何種具體策略角色215五、一個實際應(yīng)用策略模式的例子215六、在什么情況下應(yīng)當使用策略模式218七、策略模式的優(yōu)點和缺點218八、其它219C#設(shè)計模式〔1

課本:《C#設(shè)計模式》,電子工業(yè)出版社,ISBN7-5053-8979-3。33元含光盤。課程內(nèi)容:設(shè)計模式來源:亞歷山大的建筑模式、Gamma等人〔1995創(chuàng)作的"DesignPatterns:ElementsofReusableSoftware"。這本書通常被稱作"GangofFour"或"GoF",開創(chuàng)性的創(chuàng)造了《設(shè)計模式》。也有人說"三十六計"就是"模式"。

一、

C#面向?qū)ο蟪绦蛟O(shè)計復(fù)習(xí)

點擊下載,內(nèi)容包括:

字段與屬性.cs

屬性、方法作用范圍.cs

一加到一百.cs

使用接口排序<2>.cs

使用接口排序<1>.cs

求質(zhì)數(shù).cs

冒泡法排序.cs

九九表.cs

靜態(tài)與非靜態(tài).cs

構(gòu)造函數(shù).cs

方法重載.cs

多態(tài)性.cs

遞歸求階乘.cs

打印三角形.cs

傳值調(diào)用與引用調(diào)用.cs二、

設(shè)計模式舉例在設(shè)計模式中有一種模式叫Builder模式,其原理如下:我們可以將Builder理解成電飯鍋,給這個Builder放進去米和水,經(jīng)過Builder的Build后,我們就可以取出香噴噴的米飯了。

C#中有一個類叫StringBuilder,輸入必要的信息后,就可以取出對應(yīng)的String。其使用方法如下:using

System;

using

System.Text;

class

Exam

{

publicstaticvoid

Main<>

{

StringBuilder

sb

=

new

StringBuilder<>;

sb.Append<'a',2>;

sb.Append<'b',3>;

sb.Append<'c',4>;

Console.WriteLine<sb.ToString<>>;

//打印出

aabbbcccc

sb.Remove<0,

sb.Length>;

//清除sb中的所有信息

}

}程序執(zhí)行結(jié)果為:aabbbcccc

請使用StringBuilder對以下打印三角型的程序進行改寫,寫出新程序。using

System;

publicclass

Exam

{

publicstaticvoid

Main<>

{

Console.Write<"請輸入行數(shù):">;

int

lines

=

int.Parse<Console.ReadLine<>>;

Console.WriteLine<"">;

for<int

i=1;

i<=lines

;

i++>

{

for<int

k=1;

k<=

lines-i;

k++>

Console.Write<"

">;

for<int

j=1;

j<=i*2-1;

j++>

Console.Write<"*">;

Console.WriteLine<"">;

}

}

}答:using

System;

using

System.Text;

class

Exam

{

publicstaticvoid

Main<>

{

Console.Write<"請輸入行數(shù):">;

int

lines

=

int.Parse<Console.ReadLine<>>;

Console.WriteLine<"">;

StringBuilder

sb

=

new

StringBuilder<>;

for<int

i=1;

i<=lines

;

i++>

{

sb.Append<'

',

lines-i>;

sb.Append<'*',

i*2-1>;

Console.WriteLine<sb.ToString<>>;

sb.Remove<0,

sb.Length>;

}

}

}三、

先有雞還是先有蛋?到底是先有雞還是先有蛋?看下面的代碼:using

System;

class

Client

{

publicstaticvoid

Main

<>

{

Base

b

=

new

Base<>;

Derived

d

=

new

Derived<>;

b.d

=

d;

Console.WriteLine<b.d.m>;

}

}

class

Base

{

publicint

n

=

9;

public

Derived

d;

}

class

Derived

:

Base

{

publicint

m

=

10;

}Derived繼承自Base,可以說沒有Base就沒有Derived,可Base里面有一個成員是Derived類型。到底是先有雞還是先有蛋?這個程序可以正常編譯執(zhí)行并打印結(jié)果10。四、

大瓶子套小瓶子還是小瓶子套大瓶子?另外一個例子:using

System;

class

Client

{

publicstaticvoid

Main

<>

{

A

a

=

new

A<>;

B

b

=

new

B<>;

a.b

=

b;

b.a

=

a;

}

}

class

A

{

public

B

b;

}

class

B

{

public

A

a;

}上面的代碼似乎描述了"a包含b,b包含a"的關(guān)系,到底是大瓶子套小瓶子還是小瓶子套大瓶子呢?五、

.net本質(zhì)關(guān)于"先有雞還是先有蛋"的程序,系統(tǒng)運行后,內(nèi)存結(jié)構(gòu)如下:

由圖中可以看出,根本不存在雞與蛋的問題,而是型與值的問題以及指針引用的問題。關(guān)于"大瓶子套小瓶子還是小瓶子套大瓶子"問題,系統(tǒng)運行后,內(nèi)存結(jié)構(gòu)如下:

由于是指針引用,所以也無所謂大瓶子還是小瓶子了。關(guān)于更多內(nèi)容可以參考《.NET本質(zhì)論第1卷:公共語言運行庫》。C#設(shè)計模式〔2《人月神話》焦油坑、沒有銀彈

*軟件腐化的原因:問題所在

設(shè)計目標

過于僵硬

可擴展性〔新性能可以很容易加入系統(tǒng)

過于脆弱

靈活性〔修改不會波及其它

復(fù)用率低

粘度過高

可插入性〔新功能容易加入系統(tǒng)〔氣囊加入方向盤*提高系統(tǒng)可復(fù)用性的幾點原則:

傳統(tǒng)復(fù)用:

1.代碼的粘帖復(fù)用

2.算法的復(fù)用

3.數(shù)據(jù)結(jié)構(gòu)的復(fù)用*可維護性與可復(fù)用性并不完全一致*對可維護性的支持:一、"開放-封閉"原則<OCP>Open-ClosedPrinciple原則講的是:一個軟件實體應(yīng)當對擴展開放,對修改關(guān)閉。優(yōu)點:

通過擴展已有軟件系統(tǒng),可以提供新的行為,以滿足對軟件的新的需求,使變化中的軟件有一定的適應(yīng)性和靈活性。

已有軟件模塊,特別是最重要的抽象層模塊不能再修改,這使變化中的軟件系統(tǒng)有一定的穩(wěn)定性和延續(xù)性。例子:玉帝招安美猴王

當年大鬧天宮便是美猴王對玉帝的新挑戰(zhàn)。美猴王說:"'皇帝輪流做,明年到我家。'只教他搬出去,將天宮讓于我!"對于這項挑戰(zhàn),太白金星給玉皇大帝提出的建議是:"降一道招安圣旨,宣上界來…,一則不勞師動眾,二則收仙有道也。"換而言之,不勞師動眾、不破壞天規(guī)便是"閉",收仙有道便是"開"。招安之道便是玉帝天庭的"開放-封閉"原則。招安之法的關(guān)鍵便是不允許更改現(xiàn)有的天庭秩序,但允許將妖猴納入現(xiàn)有秩序中,從而擴展了這一秩序。用面向?qū)ο蟮恼Z言來講,不允許更改的是系統(tǒng)的抽象層,而允許更改的是系統(tǒng)的實現(xiàn)層。二、里氏代換原則〔LSPLiskovSubstitutionPrinciple〔里氏代換原則:子類型<subtype>必須能夠替換它們的基類型。白馬、黑馬

反過來的代換不成立

《墨子·小取》說:"娣,美人也,愛娣,非愛美人也……"娣便是妹妹,哥哥喜愛妹妹,是因為兩人是兄妹關(guān)系,而不是因為妹妹是個美人。因此,喜愛妹妹不等同于喜愛美人。用面向?qū)ο笳Z言描述,美人是基類,妹妹是美人的子類。哥哥作為一個有"喜愛<>"方法,接受妹妹作為參數(shù)。那么,這個"喜愛<>"方法一般不能接受美人的實例。一個違反LSP的簡單例子〔長方形和正方形publicclass

Rectangle

{

privatelong

width;

privatelong

height;

publicvoid

setWidth<long

width>

{

this.width

=

width;

}

publiclong

getWidth<>

{

returnthis.width;

}

publicvoid

setHeight<long

height>

{

this.height

=

height;

}

publiclong

getHeight<>

{

returnthis.height;

}

}

publicclass

Square

{

privatelong

side;

publicvoid

setSide<long

side>

{

this.side

=

side;

}

publiclong

getSide<>

{

return

side;

}

}

正方形不可以做長方形的子類using

System;

publicclass

Rectangle

{

privatelong

width;

privatelong

height;

publicvoid

setWidth<long

width>

{

this.width

=

width;

}

publiclong

getWidth<>

{

returnthis.width;

}

publicvoid

setHeight<long

height>

{

this.height

=

height;

}

publiclong

getHeight<>

{

returnthis.height;

}

}

publicclass

Square

:

Rectangle

{

privatelong

side;

publicvoid

setWidth<long

width>

{

setSide<width>;

}

publiclong

getWidth<>

{

return

getSide<>;

}

publicvoid

setHeight<long

height>

{

setSide<height>;

}

publiclong

getHeight<>

{

return

getSide<>;

}

publiclong

getSide<>

{

return

side;

}

publicvoid

setSide<long

side>

{

this.side

=

side;

}

}

publicclass

SmartTest

{

publicvoid

resize<Rectangle

r>

{

while

<r.getHeight<>

>=

r.getWidth<>

>

{

r.setWidth<r.getWidth<>

+

1>;

}

}

}

在執(zhí)行SmartTest的resize方法時,如果傳入的是長方形對象,當高度大于寬度時,會自動增加寬度直到超出高度。但是如果傳入的是正方形對象,則會陷入死循環(huán)。代碼重構(gòu)publicinterface

Quadrangle

{

publiclong

getWidth<>;

publiclong

getHeight<>;

}

publicclass

Rectangle

:

Quadrangle

{

privatelong

width;

privatelong

height;

publicvoid

setWidth<long

width>

{

this.width

=

width;

}

publiclong

getWidth<>

{

returnthis.width;

}

publicvoid

setHeight<long

height>

{

this.height

=

height;

}

publiclong

getHeight<>

{

returnthis.height;

}

}

publicclass

Square

:

Quadrangle

{

privatelong

side;

publicvoid

setSide<long

side>

{

this.side

=

side;

}

publiclong

getSide<>

{

return

side;

}

publiclong

getWidth<>

{

return

getSide<>;

}

publiclong

getHeight<>

{

return

getSide<>;

}

}C#設(shè)計模式〔3三、

依賴倒置原則<DIP>依賴倒置〔DependenceInversionPrinciple原則講的是:要依賴于抽象,不要依賴于具體。簡單的說,依賴倒置原則要求客戶端依賴于抽象耦合。原則表述:抽象不應(yīng)當依賴于細節(jié);細節(jié)應(yīng)當依賴于抽象;

要針對接口編程,不針對實現(xiàn)編程。反面例子:

缺點:耦合太緊密,Light發(fā)生變化將影響ToggleSwitch。解決辦法一:

將Light作成Abstract,然后具體類繼承自Light。

優(yōu)點:ToggleSwitch依賴于抽象類Light,具有更高的穩(wěn)定性,而BulbLight與TubeLight繼承自Light,可以根據(jù)"開放-封閉"原則進行擴展。只要Light不發(fā)生變化,BulbLight與TubeLight的變化就不會波及ToggleSwitch。缺點:如果用ToggleSwitch控制一臺電視就很困難了。總不能讓TV繼承自Light吧。解決方法二:

優(yōu)點:更為通用、更為穩(wěn)定。結(jié)論:

使用傳統(tǒng)過程化程序設(shè)計所創(chuàng)建的依賴關(guān)系,策略依賴于細節(jié),這是糟糕的,因為策略受到細節(jié)改變的影響。依賴倒置原則使細節(jié)和策略都依賴于抽象,抽象的穩(wěn)定性決定了系統(tǒng)的穩(wěn)定性。四、

接口隔離原則〔ISP接口隔離原則〔InterfaceSegregationPrinciple講的是:使用多個專門的接口比使用單一的總接口總要好。換而言之,從一個客戶類的角度來講:一個類對另外一個類的依賴性應(yīng)當是建立在最小接口上的。過于臃腫的接口是對接口的污染。不應(yīng)該強迫客戶依賴于它們不用的方法。Myobject-orientedumbrella〔摘自DesignPatternsExplainedLetmetellyouaboutmygreatumbrella.Itislargeenoughtogetinto!Infact,threeorfourotherpeoplecangetinitwithme.Whileweareinit,stayingoutoftherain,Icanmoveitfromoneplacetoanother.IthasastereosystemtokeepmeentertainedwhileIstaydry.Amazinglyenough,itcanalsoconditiontheairtomakeitwarmerorcolder.Itisonecoolumbrella.Myumbrellaisconvenient.Itsitstherewaitingforme.IthaswheelsonitsothatIdonothavetocarryitaround.Idon'tevenhavetopushitbecauseitcanpropelitself.Sometimes,Iwillopenthetopofmyumbrellatoletinthesun.<WhyIamusingmyumbrellawhenitissunnyoutsideisbeyondme!>InSeattle,therearehundredsofthousandsoftheseumbrellasinallkindsofcolors.Mostpeoplecallthemcars.實現(xiàn)方法:

1、

使用委托分離接口

2、

使用多重繼承分離接口五、

合成/聚合復(fù)用原則〔CARP合成/聚合復(fù)用原則〔Composite/AggregateReusePrinciple或CARP經(jīng)常又叫做合成復(fù)用原則〔CompositeReusePrinciple或CRP,就是在一個新的對象里面使用一些已有的對象,使之成為新對象的一部分;新對象通過向這些對象的委派達到復(fù)用已有功能的目的。簡而言之,要盡量使用合成/聚合,盡量不要使用繼承。oDesigntointerfaces.

oFavorcompositionoverinheritance.

oFindwhatvariesandencapsulateit.

〔摘自:DesignPatternsExplained區(qū)分"Has-A"與"Is-A""Is-A"是嚴格的分類學(xué)意義上定義,意思是一個類是另一個類的"一種"。而"Has-A"則不同,它表示某一個角色具有某一項責任。導(dǎo)致錯誤的使用繼承而不是合成/聚合的一個常見的原因是錯誤的把"Has-A"當作"Is-A"。例如:

實際上,雇員、經(jīng)理、學(xué)生描述的是一種角色,比如一個人是"經(jīng)理"必然是"雇員",另外一個人可能是"學(xué)生雇員",在上面的設(shè)計中,一個人無法同時擁有多個角色,是"雇員"就不能再是"學(xué)生"了,這顯然是不合理的。錯誤源于把"角色"的等級結(jié)構(gòu)與"人"的等級結(jié)構(gòu)混淆起來,誤把"Has-A"當作"Is-A"。解決辦法:六、

迪米特法則〔LoD迪米特法則〔LawofDemeter或簡寫LoD又叫最少知識原則〔LeastKnowledgePrinciple或簡寫為LKP,也就是說,一個對象應(yīng)當對其它對象有盡可能少的了解。其它表述:

只與你直接的朋友們通信

不要跟"陌生人"說話

每一個軟件單位對其它的單位都只有最少的知識,而且局限于那些與本單位密切相關(guān)的軟件單位。迪米特法則與設(shè)計模式

Facade模式、Mediator模式使民無知

《老子》第三章曰:"是以圣人之治,虛其心,實其腹,弱其志,常使民無知無欲。"使被"統(tǒng)治"的對象"愚昧"化,處于"無知"的狀態(tài),可以使"統(tǒng)治"的成本降低。

所謂"最少知識"原則,實際上便是老子的"使民無知"的統(tǒng)治之術(shù)。不相往來

《老子》云:"小國寡民……鄰國相望,雞犬之聲相聞,民至老死,不相往來。"將被統(tǒng)治的對象隔離開來,使它們沒有直接的通信,可以達到分化瓦解,繼而分而治之的效果。迪米特法則與老子的"小國寡民"的統(tǒng)治之術(shù)不謀而合。C#設(shè)計模式〔4-SimpleFactoryPattern工廠模式專門負責將大量有共同接口的類實例化。工廠模式可以動態(tài)決定將哪一個類實例化,不必事先知道每次要實例化哪一個類。工廠模式有以下幾種形態(tài):簡單工廠〔SimpleFactory模式工廠方法〔FactoryMethod模式抽象工廠〔AbstractFactory模式一、

簡單工廠〔SimpleFactory模式SimpleFactory模式根據(jù)提供給它的數(shù)據(jù),返回幾個可能類中的一個類的實例。通常它返回的類都有一個公共的父類和公共的方法。SimpleFactory模式實際上不是GoF23個設(shè)計模式中的一員。

二、

SimpleFactory模式角色與結(jié)構(gòu):工廠類角色Creator<LightSimpleFactory>:工廠類在客戶端的直接控制下〔Create方法創(chuàng)建產(chǎn)品對象。

抽象產(chǎn)品角色Product<Light>:定義簡單工廠創(chuàng)建的對象的父類或它們共同擁有的接口。可以是一個類、抽象類或接口。

具體產(chǎn)品角色ConcreteProduct<BulbLight,TubeLight>:定義工廠具體加工出的對象。

三、程序舉例:using

System;

publicabstractclass

Light

{

publicabstractvoid

TurnOn<>;

publicabstractvoid

TurnOff<>;

}

publicclass

BulbLight

:

Light

{

publicoverridevoid

TurnOn<>

{

Console.WriteLine<"Bulb

Light

is

Turned

on">;

}

publicoverridevoid

TurnOff<>

{

Console.WriteLine<"Bulb

Light

is

Turned

off">;

}

}

publicclass

TubeLight

:

Light

{

publicoverridevoid

TurnOn<>

{

Console.WriteLine<"Tube

Light

is

Turned

on">;

}

publicoverridevoid

TurnOff<>

{

Console.WriteLine<"Tube

Light

is

Turned

off">;

}

}

publicclass

LightSimpleFactory

{

public

Light

Create<string

LightType>

{

if<LightType

==

"Bulb">

returnnew

BulbLight<>;

elseif<LightType

==

"Tube">

returnnew

TubeLight<>;

elsereturnnull;

}

}

publicclass

Client

{

publicstaticvoid

Main<>

{

LightSimpleFactory

lsf

=

new

LightSimpleFactory<>;

Light

l

=

lsf.Create<"Bulb">;

l.TurnOn<>;

l.TurnOff<>;

Console.WriteLine<"">;

l

=

lsf.Create<"Tube">;

l.TurnOn<>;

l.TurnOff<>;

}

}四、

SimpleFactory模式演化SimpleFactory模式演化〔一除了上面的用法外,在有些情況下SimpleFactory可以由抽象產(chǎn)品角色扮演,一個抽象產(chǎn)品類同時是子類的工廠。程序舉例:using

System;

publicclass

Light

{

publicvirtualvoid

TurnOn<>

{

}

publicvirtualvoid

TurnOff<>

{

}

publicstatic

Light

Create<string

LightType>

{

if<LightType

==

"Bulb">

returnnew

BulbLight<>;

elseif<LightType

==

"Tube">

returnnew

TubeLight<>;

elsereturnnull;

}

}

publicclass

BulbLight

:

Light

{

publicoverridevoid

TurnOn<>

{

Console.WriteLine<"Bulb

Light

is

Turned

on">;

}

publicoverridevoid

TurnOff<>

{

Console.WriteLine<"Bulb

Light

is

Turned

off">;

}

}

publicclass

TubeLight

:

Light

{

publicoverridevoid

TurnOn<>

{

Console.WriteLine<"Tube

Light

is

Turned

on">;

}

publicoverridevoid

TurnOff<>

{

Console.WriteLine<"Tube

Light

is

Turned

off">;

}

}

publicclass

Client

{

publicstaticvoid

Main<>

{

Light

l

=

Light.Create<"Bulb">;

l.TurnOn<>;

l.TurnOff<>;

Console.WriteLine<"">;

l

=

Light.Create<"Tube">;

l.TurnOn<>;

l.TurnOff<>;

}

}SimpleFactory模式演化〔二三個角色全部合并:

與單件模式〔Singleton相近,但是有區(qū)別。

五、

優(yōu)點與缺點:優(yōu)點:

工廠類含有必要的判斷邏輯,可以決定在什么時候創(chuàng)建哪一個產(chǎn)品類的實例,客戶端可以免除直接創(chuàng)建產(chǎn)品對象的責任,而僅僅"消費"產(chǎn)品。簡單工廠模式通過這種做法實現(xiàn)了對責任的分割。缺點:

當產(chǎn)品有復(fù)雜的多層等級結(jié)構(gòu)時,工廠類只有自己,以不變應(yīng)萬變,就是模式的缺點。因為工廠類集中了所有產(chǎn)品創(chuàng)建邏輯,一旦不能正常工作,整個系統(tǒng)都要受到影響。同時,系統(tǒng)擴展困難,一旦添加新產(chǎn)品就不得不修改工廠邏輯,有可能造成工廠邏輯過于復(fù)雜。另外,簡單工廠模式通常使用靜態(tài)工廠方法,這使得無法由子類繼承,造成工廠角色無法形成基于繼承的等級結(jié)構(gòu)。C#設(shè)計模式〔5-FactoryMethodPattern一、

工廠方法〔FactoryMethod模式工廠方法〔FactoryMethod模式是類的創(chuàng)建模式,其用意是定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將實際創(chuàng)建工作推遲到子類中。工廠方法模式是簡單工廠模式的進一步抽象和推廣。由于使用了多態(tài)性,工廠方法模式保持了簡單工廠模式的優(yōu)點,而且克服了它的缺點。在工廠方法模式中,核心的工廠類不再負責所有產(chǎn)品的創(chuàng)建,而是將具體創(chuàng)建工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現(xiàn)的接口,而不接觸哪一個產(chǎn)品類被實例化這種細節(jié)。這使得工廠方法模式可以允許系統(tǒng)在不修改工廠角色的情況下引進新產(chǎn)品。在FactoryMethod模式中,工廠類與產(chǎn)品類往往具有平行的等級結(jié)構(gòu),它們之間一一對應(yīng)。

二、

FactoryMethod模式角色與結(jié)構(gòu):抽象工廠〔Creator角色:是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對象的工廠類必須實現(xiàn)這個接口。具體工廠〔ConcreteCreator角色:這是實現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對象。在上圖中有兩個這樣的角色:BulbCreator與TubeCreator。抽象產(chǎn)品〔Product角色:工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父類或共同擁有的接口。在上圖中,這個角色是Light。具體產(chǎn)品〔ConcreteProduct角色:這個角色實現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對應(yīng)。

三、

程序舉例:using

System;

publicabstractclass

Light

{

publicabstractvoid

TurnOn<>;

publicabstractvoid

TurnOff<>;

}

publicclass

BulbLight

:

Light

{

publicoverridevoid

TurnOn<>

{

Console.WriteLine<"Bulb

Light

is

Turned

on">;

}

publicoverridevoid

TurnOff<>

{

Console.WriteLine<"Bulb

Light

is

Turned

off">;

}

}

publicclass

TubeLight

:

Light

{

publicoverridevoid

TurnOn<>

{

Console.WriteLine<"Tube

Light

is

Turned

on">;

}

publicoverridevoid

TurnOff<>

{

Console.WriteLine<"Tube

Light

is

Turned

off">;

}

}

publicabstractclass

Creator

{

publicabstract

Light

factory<>;

}

publicclass

BulbCreator

:

Creator

{

publicoverride

Light

factory<>

{

returnnew

BulbLight<>;

}

}

publicclass

TubeCreator

:

Creator

{

publicoverride

Light

factory<>

{

returnnew

TubeLight<>;

}

}

publicclass

Client

{

publicstaticvoid

Main<>

{

Creator

c1

=

new

BulbCreator<>;

Creator

c2

=

new

TubeCreator<>;

Light

l1

=

c1.factory<>;

Light

l2

=

c2.factory<>;

l1.TurnOn<>;

l1.TurnOff<>;

Console.WriteLine<"">;

l2.TurnOn<>;

l2.TurnOff<>;

}

}工廠方法的活動序列圖活動過程包括:客戶端創(chuàng)建BulbCreator對象,客戶端持有此對象的類型是Creator,而實際類型是BulbCreator。然后客戶端調(diào)用BulbCreator的factory方法,之后BulbCreator調(diào)用BulbLight的構(gòu)造函數(shù)創(chuàng)造出產(chǎn)品BulbLight對象。四、

工廠方法模式與簡單工廠模式工廠方法模式與簡單工廠模式再結(jié)構(gòu)上的不同不是很明顯。工廠方法類的核心是一個抽象工廠類,而簡單工廠模式把核心放在一個具體類上。工廠方法模式之所以有一個別名叫多態(tài)性工廠模式是因為具體工廠類都有共同的接口,或者有共同的抽象父類。當系統(tǒng)擴展需要添加新的產(chǎn)品對象時,僅僅需要添加一個具體對象以及一個具體工廠對象,原有工廠對象不需要進行任何修改,也不需要修改客戶端,很好的符合了"開放-封閉"原則。而簡單工廠模式在添加新產(chǎn)品對象后不得不修改工廠方法,擴展性不好。工廠方法模式退化后可以演變成簡單工廠模式。

五、

FactoryMethod模式演化使用接口或抽象類

抽象工廠角色和抽象場頻角色都可以選擇由接口或抽象類實現(xiàn)。使用多個工廠方法

抽象工廠角色可以規(guī)定出多于一個的工廠方法,從而使具體工廠角色實現(xiàn)這些不同的工廠方法,這些方法可以提供不同的商業(yè)邏輯,以滿足提供不同的產(chǎn)品對象的任務(wù)。產(chǎn)品的循環(huán)使用

工廠方法總是調(diào)用產(chǎn)品類的構(gòu)造函數(shù)以創(chuàng)建一個新的產(chǎn)品實例,然后將這個實例提供給客戶端。而在實際情形中,工廠方法所做的事情可以相當復(fù)雜。一個常見的復(fù)雜邏輯就是循環(huán)使用產(chǎn)品對象。工廠對象將已經(jīng)創(chuàng)建過的產(chǎn)品登記到一個聚集中,然后根據(jù)客戶所請求的產(chǎn)品狀態(tài),向聚集查詢。如果有滿足要求的產(chǎn)品對象,就直接將產(chǎn)品返回客戶端;如果聚集中沒有這樣的產(chǎn)品對象,那么就創(chuàng)建一個新的滿足要求的產(chǎn)品對象,然后將這個對象登記到聚集中,再返還給客戶端。"享元模式〔FlyweightPattern"就是這樣一個模式。多態(tài)性的喪失和模式的退化

一個工廠方法模式的實現(xiàn)依賴于工廠角色和產(chǎn)品角色的多態(tài)性。在有些情況下,這個模式可以出現(xiàn)退化。工廠方法返回的類型應(yīng)當是抽象類型,而不是具體類型。調(diào)用工廠方法的客戶端應(yīng)當依賴抽象產(chǎn)品編程,而不是具體產(chǎn)品。如果工廠僅僅返回一個具體產(chǎn)品對象,便違背了工廠方法的用意,發(fā)生退化,這時就不再是工廠模式了。工廠的等級結(jié)構(gòu):工廠對象應(yīng)當有一個抽象的超類型。如果等級結(jié)構(gòu)中只有一個具體工廠類的話,抽象工廠就可以省略,發(fā)生了退化。

六、

FactoryMethod模式與其它模式的關(guān)系與工廠方法模式有關(guān)的模式還包括:

模板方法模式、MVC模式、享元模式、備忘錄模式

七、

另外一個例子//

Factory

Method

pattern

--

Real

World

example

using

System;

using

System.Collections;

//

"Product"

abstractclass

Page

{

}

//

"ConcreteProduct"

class

SkillsPage

:

Page

{

}

//

"ConcreteProduct"

class

EducationPage

:

Page

{

}

//

"ConcreteProduct"

class

ExperiencePage

:

Page

{

}

//

"ConcreteProduct"

class

IntroductionPage

:

Page

{

}

//

"ConcreteProduct"

class

ResultsPage

:

Page

{

}

//

"ConcreteProduct"

class

ConclusionPage

:

Page

{

}

//

"ConcreteProduct"

class

SummaryPage

:

Page

{

}

//

"ConcreteProduct"

class

BibliographyPage

:

Page

{

}

//

"Creator"

abstractclass

Document

{

//

Fields

protected

ArrayList

pages

=

new

ArrayList<>;

//

Constructor

public

Document<>

{

this.CreatePages<>;

}

//

Properties

public

ArrayList

Pages

{

get{

return

pages;

}

}

//

Factory

Method

abstractpublicvoid

CreatePages<>;

}

//

"ConcreteCreator"

class

Resume

:

Document

{

//

Factory

Method

implementation

overridepublicvoid

CreatePages<>

{

pages.Add<

new

SkillsPage<>

>;

pages.Add<

new

EducationPage<>

>;

pages.Add<

new

ExperiencePage<>

>;

}

}

//

"ConcreteCreator"

class

Report

:

Document

{

//

Factory

Method

implementation

overridepublicvoid

CreatePages<>

{

pages.Add<

new

IntroductionPage<>

>;

pages.Add<

new

ResultsPage<>

>;

pages.Add<

new

ConclusionPage<>

>;

pages.Add<

new

SummaryPage<>

>;

pages.Add<

new

BibliographyPage<>

>;

}

}

///<summary>///

FactoryMethodApp

test

///</summary>class

FactoryMethodApp

{

publicstaticvoid

Main<

string[]

args

>

{

Document[]

docs

=

new

Document[

2

];

//

Note:

constructors

call

Factory

Method

docs[0]

=

new

Resume<>;

docs[1]

=

new

Report<>;

//

Display

document

pages

foreach<

Document

document

in

docs

>

{

Console.WriteLine<

""

+

document

+

"

"

>;

foreach<

Page

page

in

document.Pages

>

Console.WriteLine<

"

"

+

page

>;

}

}

}C#設(shè)計模式〔6

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論