1. 程式人生 > >C#基礎系列:委託和設計模式(2)

C#基礎系列:委託和設計模式(2)

前言:這篇打算從設計模式的角度去解析下委託的使用。我們知道使用委託可以實現物件行為(方法)的動態繫結,從而提高設計的靈活性。上次說過,方法可以理解為委託的例項,站在方法的層面,委託例項的一個非常有用的特性是它既不知道,也不關心其封裝方法所屬類的詳細資訊,對它來說最重要的是這些方法與該委託的引數和返回值的相容性。即只要方法的返回型別和引數表是相同的,則方法與委託型別相容,方法的名稱及方法所屬類等資訊委託是不關心的。有一定程式設計經驗的大俠們肯定都接觸過設計模式,其實設計模式大多數都是面向物件多型特性的體現,通過重寫子類方法去展現不同的設計需求,這樣看,既然是方法重寫,那麼方法的引數型別和返回值型別肯定是一致的,這是不是和委託的例項十分相似,這樣說來,我們通過多型去實現的設計模式是否可以用委託的形式去代替。博主覺得,為了更好的理解委託,可以從這方面著手試試。。。

此篇簡單抽取了幾個設計模式分別按照多型和委託的方式去實現,當然這裡的重點並不是講設計模式,而是為了使讀者更好地理解委託。所以設計模式的很多細節,本篇可能會略過。

一、簡單工廠模式:本篇就藉助計算器的例子加以說明。

1、多型實現簡單工廠模式。

C#
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 classProgram2{staticvoidMain(string[]args){//1.使用多型實現簡單工廠模式intx=8,y=2;variRes1=GetObject("+").Compute(x,y);var
iRes2=GetObject("-").Compute(x,y);variRes3=GetObject("*").Compute(x,y);variRes4=GetObject("/").Compute(x,y);Console.WriteLine(iRes1);Console.WriteLine(iRes2);Console.WriteLine(iRes3);Console.WriteLine(iRes4);Console.ReadKey();}staticCalculator GetObject(stringtype){Calculator oRes=null;switch(type){case"+":oRes=newAdd();break;case"-":oRes=newSubtract();break;case"*":oRes=newMultiply();break;case"/":oRes=newDivide();break;}returnoRes;}}publicclassCalculator{publicvirtualintCompute(intx,inty){return0;}}publicclassAdd:Calculator{publicoverrideintCompute(intx,inty){returnx+y;}}publicclassSubtract:Calculator{publicoverrideintCompute(intx,inty){returnx-y;}}publicclassMultiply:Calculator{publicoverrideintCompute(intx,inty){returnx*y;}}publicclassDivide:Calculator{publicoverrideintCompute(intx,inty){if(y==0){return0;}returnx/y;}}

程式碼應該很容易看懂,直接通過方法的重寫去實現,在此就不過多講解。

2、委託方式實現簡單工廠模式。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 classProgram2{staticvoidMain(string[]args){#region 2.委託實現簡單工廠模式intx=8,y=2;varoCalculator=newCalculator();variRes1=oCalculator.Compute(x,y,oCalculator.Add);//將方法作為引數傳下去variRes2=oCalculator.Compute(x,y,oCalculator.Subtract);variRes3=oCalculator.Compute(x,y,oCalculator.Multiply);variRes4=oCalculator.Compute(x,y,oCalculator.Divide);Console.WriteLine(iRes1);Console.WriteLine(iRes2);Console.WriteLine(iRes3);Console.WriteLine(iRes4);#endregionConsole.ReadKey();}}publicdelegate intDelegateCalculator(intx,inty);publicclassCalculator{    //將方法的例項傳遞進來,在Compute方法裡面執行publicintCompute(intx,inty,DelegateCalculator calculator){returncalculator(x,y);}publicintAdd(intx,inty){returnx+y;}publicintSubtract(intx,inty){returnx-y;}publicintMultiply(intx,inty){returnx *y;}publicintDivide(intx,inty){if(y==0){return0;}returnx/y;}}

這裡需要定義四個實現方法Add、Subtract、Multiply、Divide,而不用在意這四個方法在哪個類下面,只要這四個方法的的引數和返回值和委託的定義保持一致即可。這也驗證了上面說的 “站在方法的層面,委託例項的一個非常有用的特性是它既不知道,也不關心其封裝方法所屬類的詳細資訊,對它來說最重要的是這些方法與該委託的引數和返回值的相容性” 。兩種方式得到的結果是相同的:

c#基礎系列

二、觀察者模式:觀察者模式最典型的場景就是訂閱者和訂閱號的場景

1、純多型方式實現觀察者模式:這種程式碼園子裡面非常多。

C#
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 classProgram3{staticvoidMain(string[]args){// 具體主題角色通常用具體自來來實現ConcreteSubject subject=newConcreteSubject();subject.Attach(newConcreteObserver(subject,"Observer A"));subject.Attach(newConcreteObserver(subject,"Observer B")