23種經(jīng)典設(shè)計(jì)模式-C#版本_第1頁(yè)
23種經(jīng)典設(shè)計(jì)模式-C#版本_第2頁(yè)
23種經(jīng)典設(shè)計(jì)模式-C#版本_第3頁(yè)
23種經(jīng)典設(shè)計(jì)模式-C#版本_第4頁(yè)
已閱讀5頁(yè),還剩216頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

23種設(shè)計(jì)模式之C#版本?http:///r//abcdwxc/archive/2007/10/30/942834.htmI1、創(chuàng)建型模式…單件模式(SingletonPattern)動(dòng)機(jī)(Motivation):在軟件系統(tǒng)中,經(jīng)常有這樣ー些特殊的類,必須保證它們?cè)谙到y(tǒng)中只存在一個(gè)實(shí)例,才能確保它們的邏輯正確性、以及良好的效率。如何繞過常規(guī)的構(gòu)造器,提供ー種機(jī)制來保證一個(gè)類只創(chuàng)建一個(gè)實(shí)例?這應(yīng)該是類設(shè)計(jì)者的責(zé)任,而不是類使用者的責(zé)任。結(jié)構(gòu)圖:returnuniqueinstanceSingletonreturnuniqueinstancestaticinstanceO0--SingletonOperatk>n()GetSingletonDataOstaticuniqueinstancesinglelonDala意圖:保證ー個(gè)類僅有一個(gè)實(shí)例,并提供ー個(gè)訪問它的全局訪問點(diǎn)。生活的例子:適用性:(1)當(dāng)類只能有一個(gè)實(shí)例而且客戶可以從ー個(gè)眾所周知的訪問點(diǎn)訪問它時(shí)。(2)當(dāng)這個(gè)唯一實(shí)例應(yīng)該是通過子類化可擴(kuò)展的,并且客戶應(yīng)該無需更改代碼就能使用ー個(gè)擴(kuò)展的實(shí)例時(shí)。代碼實(shí)現(xiàn):(1)單線程Singleton實(shí)現(xiàn)classSingleThread_Singleton{privatestaticSingleThread_Singletoninstance=null;privateSingleThread_Singleton(){}

publicstaticSingleThread_SingletonInstanceget(if(instance==null)(instance=newSingleThread_Singleton();}returninstance;}))以上代碼在單線程情況ト不會(huì)出現(xiàn)任何問題。但是在多線程的情況下卻不是安全的。如兩個(gè)線程同時(shí)運(yùn)行到if(instance==null)判斷是否被實(shí)例化, 個(gè)線程判斷為True后,在進(jìn)行創(chuàng)建instance=newSingleThread_Singleton();之前,另ー個(gè)線程也判斷(instance==null),結(jié)果也為True.這樣就就違背了Singleton模式的原則(保證ー個(gè)類僅有一個(gè)實(shí)例).怎樣在多線程情況下實(shí)現(xiàn)Singleton?(2)多線程Singleton實(shí)現(xiàn):classMultiThread_Singleton{privatestaticvolatileMultiThread_Singletoninstance=null;privatestaticobjectlockHelper=newobject();privateMultiThread_Singleton(){}publicstaticMultiThread_SingletonInstanceTOC\o"1-5"\h\z{get{if(instance==null){lock(lockHelper)

14if14if(instance==null)TOC\o"1-5"\h\z{instance=newMultiThread_Singleton();))}return instance;))此程序?qū)Χ嗑€程是安全的,使用了一個(gè)輔助對(duì)象lockHelper,保證只有一個(gè)線程創(chuàng)建實(shí)例(如果instance為空,保證只有一ー個(gè)線程instance=newMultiThread_Singleton();創(chuàng)建唯一的ー個(gè)實(shí)例)。(DoubleCheck)請(qǐng)注意ー個(gè)關(guān)鍵字volatile,如果去掉這個(gè)關(guān)鍵字,還是有可能發(fā)生線程不是安全的。volatile保證嚴(yán)格意義的多線程編譯器在代碼編譯時(shí)對(duì)指令不進(jìn)行微調(diào)。(3)靜態(tài)Singleton實(shí)現(xiàn)classStatic_SingletonTOC\o"1-5"\h\z{publicstaticreadonlyStatic_Singletoninstance=newStatic_Singleton();privateStatic_Singleton(){})以上代碼展開等同于classStatic_Singleton(publicstaticreadonlyStatic_Singletoninstance;static Static_Singleton(){instance=newStatic_Singleton();}privateStatic_Singleton(){}}由此可以看出,完全符合Singleton的原則。優(yōu)點(diǎn):簡(jiǎn)潔,易懂缺點(diǎn):不可以實(shí)現(xiàn)帶參數(shù)實(shí)例的創(chuàng)建。(注:以上代碼及信息借鑒于李建忠老師的MSDN和TerryLee的文章。)2、創(chuàng)建型模式…抽象工廠(AbstractFactory)常規(guī)的對(duì)象創(chuàng)建方法:〃創(chuàng)建一個(gè)Road對(duì)象Roadroad=newRoad();new的問題:實(shí)現(xiàn)依賴,不能應(yīng)對(duì)“具體實(shí)例化類型”的變化。解決思路:封裝變化點(diǎn)……哪里變化,封裝哪里潛臺(tái)詞:如果沒有變化,當(dāng)然不需要額外的封裝!工廠模式的緣起變化點(diǎn)在“對(duì)象創(chuàng)建”,因此就封裝“對(duì)象創(chuàng)建”面向接口編程一一一依賴接口,而非依賴實(shí)現(xiàn)最簡(jiǎn)單的解決方法:classRoadFactory{publicstaticRoadCreateRoad(){returnnewRoad();)}〃創(chuàng)建一個(gè)Road對(duì)象Roadroad=roadFactory.CreateRoad();

創(chuàng)建一系列相互依賴對(duì)象的創(chuàng)建工作:假設(shè)ー個(gè)游戲開場(chǎng)景:我們需要構(gòu)造"道路"、"房屋"、"地道","從林"…等等對(duì)象工廠方法如下:classRoadFactoryTOC\o"1-5"\h\z{publicstaticRoadCreateRoad(){returnnewRoad();)publicstaticBuildingCreateBuilding(){returnnew Building();)public staticTunnel CreateTunnel(){returnnewTunnel();)public staticJungle CreateJungle(){1'7 returnnewJungle();))調(diào)用方式如下:1 Roadroad=RoadFactory.CreateRoad();Buildingbuilding=RoadFactory.CreateBuilding();Tunneltunnel=RoadFactory.CreateTunnel();Junglejungle=RoadFactory.CreateJungle();如上可見簡(jiǎn)單工廠的問題:不能應(yīng)對(duì)"不同系列對(duì)象"的變化。比如有不同風(fēng)格的場(chǎng)景一ー對(duì)應(yīng)不同風(fēng)格的道路,房屋、地道....如何解決:使用面向?qū)ο蟮募夹g(shù)來"封裝"變化點(diǎn)〇

動(dòng)機(jī)(Motivate):在軟件系統(tǒng)中,經(jīng)常面臨著"ー系統(tǒng)相互依賴的對(duì)象"的創(chuàng)建工作;同時(shí),由于需求的變化,往往存在更多系列對(duì)象的創(chuàng)建工作。如何應(yīng)對(duì)這種變化?如何繞過常規(guī)的對(duì)象創(chuàng)建方法(new),提供?種”封裝機(jī)制"來避免客戶程序和這種”多系列具體對(duì)象創(chuàng)建工作"的緊耦合?意圖(Intent):提供ー個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無需指定它們具體的類。 《設(shè)計(jì)模式》GOF結(jié)構(gòu)圖(Struct):適用性:.一個(gè)系統(tǒng)要獨(dú)立于它的產(chǎn)品的創(chuàng)建、組合和表示時(shí)。.ー個(gè)系統(tǒng)要由多個(gè)產(chǎn)品系統(tǒng)中的一個(gè)來配置時(shí)。.當(dāng)你要強(qiáng)調(diào)?系列相關(guān)的產(chǎn)品對(duì)象的設(shè)計(jì)以便進(jìn)行聯(lián)合使用時(shí)。.當(dāng)你提供一個(gè)產(chǎn)品類庫(kù),而只想顯示它們的接口不是實(shí)現(xiàn)時(shí)。生活例子:

河リk桎摘結(jié)構(gòu)圖代碼實(shí)現(xiàn):abstractclassAbstractFactoryTOC\o"1-5"\h\z(publicabstractAbstractProductACreateProductA();publicabstractAbstractProductsCreateProductB();)abstractclassAbstractProductA{publicabstractvoidInteract(AbstractProductsb);)abstractclassAbstractProducts{publicabstractvoidInteract(AbstractProductAa);)classClient{privateAbstractProductAAbstractProductA;4privateAbstractProductsAbstractProductB;publicClient(AbstractFactoryfactory)

AbstractProductA=factory.CreateProductA();AbstractProducts=factory.CreateProductB();)publicvoidRun()(AbstractProducts.Interact(AbstractProductA);AbstractProductA.Interact(AbstractProducts);)}classConcreteFactory1:AbstractFactory(publicoverrideAbstractProductACreateProductA()(returnnewProductAI();}publicoverrideAbstractProductsCreateProductB()(returnnewProductBI();)}classConcreteFactory2:AbstractFactory{publicoverrideAbstractProductACreateProductA()(returnnewProdcutA2();}publicoverrideAbstractProductsCreateProductB()(returnnewProductB2();)678910111213141512345678910111234567891011}1classProductAI:AbstractProductApublicoverridevoidInteract(AbstractProductsb)TOC\o"1-5"\h\z{Console.WriteLine(this.GetType().Name+"interactwith"+b.GetType().Name);))classProductBI:AbstractProductB(publicoverridevoidInteract(AbstractProductAa){Console.WriteLine(this.GetType().Name+"interactwith"+a.GetType().Name);}}classProdcutA2:AbstractProductA(publicoverridevoidInteract(AbstractProductBb){Console.WriteLine(this.GetType().Name+"interactwith"+b.GetType().Name);))classProductB2:AbstractProductB(publicoverridevoidInteract(AbstractProductAa){Console.WriteLine(this.GetType().Name+"interactwith"+a.GetType().Name);)}publicstaticvoidMain(){//AbstractfactorylAbstractFactoryfactoryl=newConcreteFactoryl();

Clientc1= new Client(factory1);c1.Run();〃Abstractfactory2AbstractFactory factory2=newConcreteFactory2();Clientc2= new Client(factory2);c2.Run();)AbstractFactory注意的幾點(diǎn):如果不存在”多系列對(duì)象創(chuàng)建"的需求變化,則沒必要應(yīng)用AbstractFactory模式,靜態(tài)工廠方法足矣。"系列對(duì)象”指的是這些對(duì)象之間有相互依賴、或作用的關(guān)系。例如游戲開發(fā)場(chǎng)景中的"道路"與"房屋"依賴,“道路”與“地道”的依賴。AbstractFactory模式主要在于應(yīng)對(duì)”新系列"的需求變動(dòng)。其缺點(diǎn)在于難以應(yīng)對(duì)”新對(duì)象“的需求變動(dòng)。AbstractFactory模式經(jīng)常和FactoryMethod模式共同組合來應(yīng)對(duì)“對(duì)象創(chuàng)建”的需求變化。3、創(chuàng)建型模式…建造者模式(Builder)Builder模式的緣起:假設(shè)創(chuàng)建游戲中的ー個(gè)房屋House設(shè)施,該房屋的構(gòu)建由幾部分組成,且各個(gè)部分富于變化。如果使用最直觀的設(shè)計(jì)方法,每ー個(gè)房屋部分的變化,都將導(dǎo)致房屋構(gòu)建的重新修正…一動(dòng)機(jī)(Motivation):在軟件系統(tǒng)中,有時(shí)候面臨?個(gè)"復(fù)雜對(duì)象”的創(chuàng)建工作,其通常由各個(gè)部分的上對(duì)象用?定克法構(gòu)成;由于需求的變化,這個(gè)復(fù)雜対象的各個(gè)部分経常面臨著劇烈的變化,但是將它們組合到ー起的算法卻相對(duì)穩(wěn)定。如何應(yīng)對(duì)種變化呢?如何提供ー種“封裝機(jī)制"來隔離出"復(fù)雜對(duì)象的各個(gè)部分"的變化,從而保持系統(tǒng)中的"穩(wěn)定構(gòu)建算法"不隨需求的改變而改變?意圖(Intent):將一個(gè)復(fù)雜対象的構(gòu)建ワ貝:表示相分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 《設(shè)計(jì)模式》GOF結(jié)構(gòu)圖(Struck:Builder-BuildPartOConcreteBuilderFetchItemInStructurebuild.BuildPart()協(xié)作(Collaborations):aClientrwwConcreteBuikSer生活中的例子:-BuildPart()*GctRcsult()aDirectornewOreclor(aConcfe!e8uilder)Constructf)GetResult()BuildPartA。BuMPartBOBuikJParlCOaConcreteBuilder減器(wr>減器(wr>代價(jià)同いい<*M).當(dāng)創(chuàng)建復(fù)雜對(duì)象的算法應(yīng)該獨(dú)立于該對(duì)象的組成部分以及它們的裝配方式時(shí)。.當(dāng)構(gòu)造過程必須允許被構(gòu)造的對(duì)象有不同的表示時(shí)。實(shí)例代碼:Builder類:publicabstractclassBuilder{public abstract void BuildDoor();public abstract void BuildWall();public abstract void BuildWindows();public abstract void BuildFloor();public abstract void BuildHouseCeiling();publicabstractHouseGetHouse();}Director類:這一部分是組合到ー起的算法(相對(duì)穩(wěn)定)。publicclassDirector{publicvoidConstruct(Builderbuilder)(builder.BuildWall();builder.BuildHouseCeiling();builder.BuildDoor();builder.BuildWindows();builder.BuildFloor();1234567891011121314151617181920212223242526272810 )11)ChineseBuilder類publicclassChineseBuilder:Builder(privateHouseChineseHouse=newHouse();publicoverridevoidBuildDoor(){Console.WriteLine("thisDoor'sstyleofChinese'*);)publicoverridevoidBuildWall(){Console.WriteLine(**thisWall*sstyleofChinese**);)publicoverridevoidBuildWindows(){Console.WriteLine(**thisWindows*sstyleofChinese**);)publicoverridevoidBuildFloor(){Console.WriteLine(**thisFloor*sstyleofChinese**);}publicoverridevoidBuildHouseCeiling(){Console.WriteLine(**thisCeiling*sstyleofChinese**);)publicoverrideHouseGetHouse(){returnChineseHouse;)}RomanBuilder類:1classRomanBuilder:BuilderprivateHouseRomanHouse=newHouse();public overridevoid BuildDoor()TOC\o"1-5"\h\z{Console.WriteLine("thisDoor'sstyleofRoman");)public overridevoid BuildWall(){Console.WriteLine("thisWall'sstyleofRoman**);}public overridevoidBuildWindows(){Console.WriteLine("thisWindows*sstyleofRoman");}public overridevoid BuildFloor(){Console.WriteLine("thisFloor*sstyleofRoman");}public overridevoid BuildHouseCeiling(){Console.WriteLine("thisCeiling*sstyleofRoman");)publicoverrideHouseGetHouse(){returnRomanHouse;})ChineseBuilder和RomanBuilder這兩個(gè)是:這個(gè)復(fù)雜對(duì)象的兩個(gè)部分經(jīng)常面臨著劇烈的變化。publicclassClient{publicstaticvoidMain(string[]args){Directordirector=newDirector();7 Builderinstance;89 Console.WriteLine(HPleaseEnterHouseNo:");1011 stringNo=Console.ReadLine();1213 stringhouseType=ConfigurationSettings.AppSettings["No"+No];1415 instance=(Builder)Assembly.Load("House").Createlnstance("House.+houseType);1617 director.Construct(instance);1819 Househouse=instance.GetHouse();20 house.Show();2122 Console.ReadLine();23 )24 )<?xmlversion="1.0"encoding="utf-8"?><configuration><appSettings><addkey="No1"value="RomanBuilder"x/add><addkey="No2"value="ChineseBuilder"></add></appSettings></configuration>Builder模式的幾個(gè)要點(diǎn):Builder模式主要用于“分步驟構(gòu)建一個(gè)復(fù)雜的對(duì)象”。在這其中“分步驟”是ー個(gè)穩(wěn)定的算法,而復(fù)雜對(duì)象的各個(gè)部分則經(jīng)常變化。Builder模式主要在于應(yīng)對(duì)“復(fù)雜對(duì)象各個(gè)部分”的頻繁需求變動(dòng)。其缺點(diǎn)在于難以應(yīng)對(duì)“分步驟構(gòu)建算法”的需求變動(dòng)。AbstractFactory模式解決"系列對(duì)象"的需求變化,Builder模式解決“對(duì)象部分”的需求變化。Builder模式通常和Composite模式組合使用。4、創(chuàng)建型模式…工廠方法模式(FactoryMethod)耦合關(guān)系:耦合關(guān)系直接決定著軟件面對(duì)變化時(shí)的行為-模塊與模塊之間的緊耦合使得軟件面對(duì)變化時(shí),相關(guān)的模塊都要隨之更改?模塊與模塊之間的松耦合使得軟件面對(duì)變化時(shí),一些模塊更容易被替換或者更改,但其他模塊保持不變動(dòng)機(jī)(Motivation):在軟件系統(tǒng)中,由于需求的變化,"這個(gè)對(duì)象的具體實(shí)現(xiàn)"經(jīng)常面臨著劇烈的變化,但它卻仃比較穩(wěn)定的接口。

如何應(yīng)對(duì)這種變化呢?提供ー種封裝機(jī)制來隔離出“這個(gè)易變對(duì)象"的變化,從而保持系統(tǒng)中"其它依賴的對(duì)象"不隨需求的變化而變化。意圖(Intent):定義?個(gè)用戶創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例哪ー個(gè)類。FactoryMethod使一個(gè)類的實(shí)例化延遲到子類。 《設(shè)計(jì)模式》GOF結(jié)構(gòu)圖(Struct):生活實(shí)例:適用性:.當(dāng)ー個(gè)類不知道它所必須創(chuàng)建的對(duì)象類的時(shí)候。.當(dāng)?個(gè)類希望由它『類來指定它所創(chuàng)建對(duì)象的時(shí)候。.當(dāng)類將創(chuàng)建對(duì)象的職責(zé)委托給多個(gè)幫助子類中的某個(gè),并且你希望將哪ー個(gè)幫助子類是代理者這一信息局部化的時(shí)候。

實(shí)例代碼:CarFactory類:publicabstractclassCarFactoryTOC\o"1-5"\h\z(publicabstractCarCarCreate();)Car類:publicabstractclassCar(public abstract void StartUp();public abstract void Run();public abstract void Stop();TOC\o"1-5"\h\z}HongQiCarFactory類:publicclassHongQiCarFactory:CarFactory(publicoverrideCarCarCreate()(returnnewHongQiCar();))BMWCarFactory類:publicclassBMWCarFactory:CarFactory(public overrideCarCarCreate(){returnnewBMWCar();)}HongQiCar類:publicclassHongQiCar:Car{publicoverridevoidStartUpOConsole.WriteLine(MTestHongQiCarstart-upspeed!*');TOC\o"1-5"\h\z}publicoverride voidRun(){Console.WriteLine("TheHongQiCarrunisveryquickly!");)publicoverridevoidStop(){Console.WriteLine("Theslowstoptimeis3second");))BMWCar類:publicclassBMWCar:Car{public override void StartUp()(Console.WriteLine("TheBMWCarstart-upspeedisveryquickly");)public override void Run(){Console.WriteLine("TheBMWCarrunisquitelyfastandsafe!!!");)publicoverridevoidStop(){Console.WriteLine("Theslowstoptimeis2second");))app.config1<?xmlversion="1.0"encoding="utf-8"?>2<configuration>3<appSettings>4<addkey="No1"value="HongQiCarFactory"/>5 <addkey="No2"value="BMWCarFactory"/>6</appSettings>7</configuration>Program類:1classProgramstaticvoidMain(string[]args)Console.WriteLine(HPleaseEnterFactoryMethodNo:");Console.WriteLine("…Console.WriteLine("noFactoryMethod");Console.WriteLine("noFactoryMethod");Console.WriteLine("1HongQiCarFactory");Console.WriteLine("1HongQiCarFactory");Console.WriteLine("2BMWCarFactory");Console.WriteLine("2BMWCarFactory");10Console.WriteLine("***11intno=Int32.Parse(Console.ReadLine().ToString());12stringfactoryType=ConfigurationManager.AppSettings["No"+no];13//CarFactoryfactory=newHongQiCarFactory();14CarFactoryfactory10Console.WriteLine("***11intno=Int32.Parse(Console.ReadLine().ToString());12stringfactoryType=ConfigurationManager.AppSettings["No"+no];13//CarFactoryfactory=newHongQiCarFactory();14CarFactoryfactory=(CarFactory)Assembly.Load("FactoryMehtod").Createlnstance("FactoryMehtod."+factoryType);//注意:確保這個(gè)項(xiàng)目的程序集名稱為FactoryMehtodCarcar=factory.CarCreate();car.StartUp();car.Run();car.Stop();})FactoryMethod模式的幾個(gè)要點(diǎn):FactoryMethod模式主要用于隔離類對(duì)蒙的使用者和具體類型之間的相介關(guān)系。面對(duì)一個(gè)經(jīng)常變化的具體類型,緊耦合關(guān)系會(huì)導(dǎo)致軟件的脆弱。FactoryMethod模式通過面向?qū)ο蟮氖址?將所要?jiǎng)?chuàng)建的具體對(duì)象工作延遲到子類,從而實(shí)現(xiàn)ー種擴(kuò)展(而非更改)的策略,較好地解決了這種緊耦合關(guān)系。FactoryMehtod模式解決"單個(gè)對(duì)象"的需求變化,AbstractFactory模式解決‘系列對(duì)象”的需求變化,Builder模式解決“對(duì)象部分”的需求變化。5、創(chuàng)建型模式…原型模式(Prototype)依賴關(guān)系倒置:抽象不應(yīng)該依賴于實(shí)現(xiàn)細(xì)節(jié),實(shí)現(xiàn)細(xì)節(jié)應(yīng)該依賴于抽象。抽象不應(yīng)該依賴于實(shí)現(xiàn)細(xì)節(jié),實(shí)現(xiàn)細(xì)節(jié)應(yīng)該依賴于抽象。?抽象A直接依賴于實(shí)現(xiàn)細(xì)節(jié)bー抽象?抽象A直接依賴于實(shí)現(xiàn)細(xì)節(jié)bー抽象A依賴于抽象B,實(shí)現(xiàn)細(xì)節(jié)b依賴于抽象B吆/シ實(shí)現(xiàn)細(xì)節(jié)b抽象A抽象B實(shí)現(xiàn)細(xì)節(jié)b動(dòng)機(jī)(Motivate):在軟件系統(tǒng)中,經(jīng)常面臨著“某些結(jié)構(gòu)復(fù)雜的對(duì)象”的創(chuàng)建工作;由于需求的變化,這旳對(duì)象經(jīng)常面臨著劇烈的變化,但是它們卻擁有比較穩(wěn)定一致的接口。如何應(yīng)對(duì)這種變化?如何向“客戶程序(使用這些對(duì)象的程序)"隔離出“這些易變對(duì)象”,從而使得“依賴這些易變對(duì)象的客ハ程序”不隨著需求改變而改變?意圖(Intent):用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。 《設(shè)計(jì)模式》G0F結(jié)構(gòu)圖(Struct):生活例子:適用性:.當(dāng)一個(gè)系統(tǒng)應(yīng)該獨(dú)立于它的產(chǎn)品創(chuàng)建,構(gòu)成和表示時(shí);.當(dāng)要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí),例如,通過動(dòng)態(tài)裝載;.為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠類層次時(shí);.當(dāng)ー個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的種時(shí)。建立相應(yīng)數(shù)H的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便ー些。示意性代碼例子:publicabstractclassNormalActor{publicabstractNormalActorclone();123456789123456789publicclassNormalActorA:NormalActor(publicoverrideNormalActorclone()(Console.WriteLine('*NormalActorAiscall");return(NormalActor)this.MemberwiseClone();})publicclassNormalActorB:NormalActor(publicoverrideNormalActorclone()(Console.WriteLine("NormalActorBwascalled");return(NormalActor)this.MemberwiseClone();})publicclassGameSystem(publicvoidRun(NormalActornormalActor){NormalActornormalActorl=normalActor.clone();NormalActornormalActor2=normalActor.clone();NormalActornormalActor3=normalActor.clone();NormalActornormalActor4=normalActor.clone();NormalActornormalActor5=normalActor.clone();)}classprogram

staticvoidMain(string[]args)GameSystemgameSystem=newGameSystem();gameSystem.Run(newNormalActorA());)}如果又需要?jiǎng)?chuàng)建新的對(duì)象(flyActor),只需創(chuàng)建此抽象類,然后具體類進(jìn)行克隆。publicabstractclassFlyActor{publicabstractFlyActorclone();)publicclassFlyActorB:FlyActor(///<summary>//Z淺拷貝,如果用深拷貝,可使用序列化III</summary>///<returns></returns>publicoverrideFlyActorclone()(return(FlyActor)this.MemberwiseClone();})此時(shí),調(diào)用的Main。函數(shù)只需如下:classProgram{staticvoidMain(string[]args){GameSystemgameSystem=newGameSystem。;gameSystem.Run(newNormalActorA。,newFlyActorB。);)

Prototype的幾個(gè)要點(diǎn):Prototype模式同樣用于隔離類對(duì)象的使用者和具體類型(易變類)之間的耦合關(guān)系,它同樣要求這些“易變類"擁有"穩(wěn)定的接口”。Prototype模式對(duì)于“如何創(chuàng)建易變類的實(shí)體對(duì)象“采用“原型克隆”的方法來做,它使得我們可以非常靈活地動(dòng)態(tài)創(chuàng)建“擁有某些穩(wěn)定接口中”的新對(duì)象一一一所需工作僅僅是注冊(cè)的地方不斷地Clone.Prototype模式中的Clone方法可以利用.net中的object類的memberwiseClone()方法或者序列化來實(shí)現(xiàn)深拷貝??偨Y(jié)一有關(guān)創(chuàng)建型模式的使用Singleton模式解決的是實(shí)體對(duì)象個(gè)數(shù)的問題。除了Singleton之外,其他創(chuàng)建型模式解決的是都是new所帶來的耦合關(guān)系。FactoryMethod,AbstractFactory,Builder都需要一個(gè)額外的工廠類來負(fù)責(zé)實(shí)例化“易變對(duì)象”,而Prototype則是通過原型(ー個(gè)特殊的工廠類)來克隆“易變對(duì)象”〇如果遇到“易變類”,起初的設(shè)計(jì)通常從FactoryMehtod開始,當(dāng)遇到更多的復(fù)雜變化時(shí),再考慮重重構(gòu)為其他三種エ廠模式(AbstractFactory,Builder,Prototype).6、結(jié)構(gòu)型模式…適配器模式(AdapterPattern)適配(轉(zhuǎn)換)的概念無處不在 適配,即在不改變?cè)袑?shí)現(xiàn)的基礎(chǔ)上,將原先不兼容的接口轉(zhuǎn)換為兼容的接口。例如:二轉(zhuǎn)換為三箱插頭,將高電壓轉(zhuǎn)換為低電壓等。

動(dòng)機(jī)(Motivate):在軟件系統(tǒng)中,由于應(yīng)用環(huán)境的變化,常常需要將“一些現(xiàn)存的對(duì)象”放在新的環(huán)境中應(yīng)用,但是新環(huán)境要求的接口是這些現(xiàn)存對(duì)象所不滿足的〇那么如何應(yīng)對(duì)這種“遷移的變化”?如何既能利用現(xiàn)有対象的良好實(shí)現(xiàn),同時(shí)又能滿足新的應(yīng)用環(huán)境所要求的接口?這就是本文要說的Adapter模式。意圖(Intent):將?個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以ー起工作。《設(shè)計(jì)模式》GOF結(jié)構(gòu)(Struct):圖1:對(duì)象適配器

<<Interface?圖2:類適配器生活中的例子:轉(zhuǎn)齒1/2,<<Interface?圖2:類適配器生活中的例子:轉(zhuǎn)齒1/2,陽(yáng)槽適配器1/4‘陰槽T7彳甜1/4‘陰槽1/4,陽(yáng)槽適用性:.系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。.想要建立一個(gè)可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的ー些類,包括ー些可能在將來引進(jìn)的類ー起工作?這些源類不一定有很復(fù)雜的接口。.(對(duì)對(duì)象適配器而言)在設(shè)計(jì)里,需要改變多個(gè)己有子類的接口,如果使用類的適配器模式,就要針對(duì)每ー個(gè)子類做ー個(gè)適配器,而這不太實(shí)際。示意性代碼實(shí)例:interfaceIStackvoidvoidPush(objectitem);voidPop();

objectPeek();)〃對(duì)象適配器(Adapter與Adaptee組合的關(guān)系)publicclassAdapter:IStack〃適配對(duì)象{ArrayListadaptee;〃被適配的對(duì)象public Adapter()TOC\o"1-5"\h\z(adaptee=newArrayList();)public void Push(objectitem){adaptee.Add(item);)publicvoidPop(){adaptee.RemoveAt(adaptee.Count- 1);)publicobjectPeek(){returnadaptee[adaptee.Count-1];))類適配器publicclassAdapter:ArrayList,IStack{public void Push(objectitem)TOC\o"1-5"\h\z{this.Add(item);}public void Pop()(this.RemoveAt(this.Count-1);

publicobjectPeek(){returnthis[this.Count-1];))Adapter模式的幾個(gè)要點(diǎn):Adapter模式主要應(yīng)用于“希望復(fù)用ー些現(xiàn)存的類,但是接口又與復(fù)用環(huán)境要求不一致的情況”,在遺留代碼復(fù)用、類庫(kù)遷移等方面非常有用。GOF23定義了兩種Adapter模式的實(shí)現(xiàn)結(jié)構(gòu):對(duì)象適配器和類適配器。但類適配器采用“多繼承”的實(shí)現(xiàn)方式,帶來不良的高糊合,所以一般不推薦使用。對(duì)象適配器采用“對(duì)象組合”的方式,更符合松耦介精神。Adapter模式可以實(shí)現(xiàn)的非常靈活,不必拘泥于GOF23中定義的兩種結(jié)構(gòu)。例如,完全可以將Adapter模式中的“現(xiàn)存對(duì)象”作為新的接口方法參數(shù),來達(dá)到適配的目的。Adapter模式本身要求我們盡可能地使用”面向接口的編程”風(fēng)格,這樣才能在后期很方便的適配。.NET框架中的Adapter應(yīng)用:(1)在?Net中復(fù)用com對(duì)象:Com對(duì)象不符合.net對(duì)象的接口使用tlbimp.exe來創(chuàng)建一?個(gè)RuntimeCallableWrapper(RCW)以使其符合.net對(duì)象的接口。(2).NET數(shù)據(jù)訪問類(Adapter變體):各種數(shù)據(jù)庫(kù)并沒有提供DataSet接口使用DBDataAdapter可以將任何各數(shù)據(jù)庫(kù)訪問/存取適配到ー個(gè)DataSet對(duì)象上。(3)集合類中對(duì)現(xiàn)有對(duì)象的排序(Adapter變體);現(xiàn)有對(duì)象未實(shí)現(xiàn)IComparable接口實(shí)現(xiàn)ー個(gè)排序適配器(繼承IComparer接口),然后在其Compare方法中對(duì)兩個(gè)對(duì)象進(jìn)行比較。

7、結(jié)構(gòu)型模式一橋接模式(BridgePattern)動(dòng)機(jī)(Motivate):在軟件系統(tǒng)中,某些類型由于自身的邏輯,它具有兩個(gè)或多個(gè)維度的變化,那么如何應(yīng)對(duì)這種“多維度的變化”?如何利用面向?qū)ο蟮募夹g(shù)來使得該類型能夠輕松的沿著多個(gè)方向進(jìn)行變化,而又不引入額外的復(fù)雜度?意圖(Intent):將抽象部分與實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化。 《設(shè)計(jì)模式》G0F結(jié)構(gòu)圖(Struct):生活中的例子:我想大家小時(shí)候都有用蠟筆畫畫的經(jīng)歷吧。紅紅綠綠的蠟筆一大盒,根據(jù)想象描繪出格式圖樣。而毛筆下的國(guó)畫更是工筆寫意,各展風(fēng)采。而今天我們的故事從蠟筆與毛筆說起。設(shè)想要繪制一幅圖畫,藍(lán)天、白云、綠樹、小巧,如果畫面尺寸很大,那么用蠟筆繪制就會(huì)遇到點(diǎn)麻煩。畢竟細(xì)細(xì)的蠟筆要涂出一片藍(lán)天,是有些麻煩。如果有可能,最好有套大號(hào)蠟筆,粗粗的蠟筆很快能涂抹完成。至于色彩嗎,最好每種顏色來支粗的,除了藍(lán)天還有綠地呢。這樣,如果ー套12種顏色的蠟筆,我們需要兩套24支,同種顏色的一粗一細(xì)。呵呵,畫還沒畫,開始做夢(mèng)了:要是再有一套中號(hào)蠟筆就更好了,這樣,不多不少總共36支蠟筆。再看看毛筆這ー邊,居然如此簡(jiǎn)陋:ー套水彩12色,外加大中小三支毛筆。你可別小瞧這"簡(jiǎn)陋”的組合,畫藍(lán)天用大毛筆,畫小鳥用小毛筆,各具特色。呵呵,您是不是已經(jīng)看出來了,不錯(cuò),我今天要說的就是Bridge模式。為了一幅畫,我們需要準(zhǔn)備36支型號(hào)不同的蠟筆,而改用毛筆三支就夠了,當(dāng)然還要搭配上12種顏料。通過Bridge模式,我們把乘法運(yùn)算3x12=36改為了加法運(yùn)算3+12=15,這ー改進(jìn)可不小。那么我們這里蠟筆和毛筆到底有什么區(qū)別呢?實(shí)際上,蠟筆和毛筆的關(guān)鍵?個(gè)區(qū)別就在于筆和顏色是否能夠分離。[GOF95】橋梁模式的用意是"將抽象化(Abstraction)與實(shí)現(xiàn)化(Impiementation)脫耦,使得二者可以獨(dú)立地變化"〇關(guān)鍵就在于能否脫耦。蠟筆的顏色和蠟筆本身是分不開的,所以就造成必須使用36支色彩、大小各異的蠟筆來繪制圖畫。而毛筆與顏料能夠很好的脫耦,各自獨(dú)立變化,便簡(jiǎn)化了操作。在這里,抽象層面的概念是:"毛筆用顏料作畫",而在實(shí)現(xiàn)時(shí),毛筆有大中小三號(hào),顏料有紅綠藍(lán)等12種,于是便可出現(xiàn)3x12種組合。每個(gè)參與者(毛筆與顏料)都可以在自己的自由度上隨意轉(zhuǎn)換。

123456781234512345123412蠟筆由于無法將筆與顏色分離,造成筆與顏色兩個(gè)自由度無法單獨(dú)變化,使得只有創(chuàng)建36種對(duì)象才能完成任務(wù)。Bridge模式將繼承關(guān)系轉(zhuǎn)換為組合關(guān)系,從而降低了系統(tǒng)間的耦合,減少了代碼編寫量。代碼實(shí)現(xiàn):abstractclassBrush(protectedColorc;publicabstractvoidPaint();publicvoidSetColor(Colorc){this.c=c;})classBigBrush:Brush(publicoverridevoidPaint(){Console.WriteLine(HUsingbigbrushandcolor{0}painting'*,c.color);})classSmallBrush:Brush(publicoverridevoidPaint(){Console.WriteLine("Usingsmallbrushandcolor{0}painting*',c.color);}}classColor(publicstringcolor;)classRed:Color

3451234512345123456789101112131415161718publicRed(){this.color="red";}classGreen:Color(publicGreen(){this.color="green";})classBlue:Color(publicBlue(){/r

溫馨提示

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

評(píng)論

0/150

提交評(píng)論