ASP.NET入門隨想之多態、接口與委托(2)
發表于:2007-06-30來源:作者:點擊數:
標簽:
上傳機制有一個很直觀的好處,如果船基類又臨時增加賽船子類, 我們在不修改已有代碼的前提下輕松完成對原有軟件的擴展,即"開放-封閉"原則(Open-Closed Principle)。如增加以下代碼并不影響控制移動方法: 賽船 麥哲倫 = new賽船(); 控制移動(麥哲倫); 只
上傳機制有一個很直觀的好處,如果船基類又臨時增加賽船子類, 我們在不修改已有代碼的前提下輕松完成對原有軟件的擴展,即"開放-封閉"原則(Open-Closed Principle)。如增加以下代碼并不影響控制移動方法:
賽船 麥哲倫 = new賽船();
控制移動(麥哲倫);
只所以功能擴展不影響控制移動方法,是因為控制移動方法只依賴于船類系的基類。如果把一個類系的公共方法集中起來,定義成抽象類(abstract),其它類只與抽象類發生依賴關系,只要抽象類的方法接口不變,其繼承子類的內部調整不影響外界的使用,最大程度達到外界與這個類系的架構(這時指依賴關系)穩定。作為一個抽象類,它具備兩個重要特征:一是方法只有接口定義沒有實現,二是子類(非抽象類繼承)必須實現抽象類的所有方法。抽象類不能實例化,也沒有必要實例化,就一空架子折騰啥呀。
■ 我是主角 - 接口與委托
OO思想一般強調類為主角,方法是類的配角,尤其抽象類系,基類與所有子類是強耦合關系,它要是倒下了,人心就散了,隊伍就難帶了。一旦抽象類需要變動(增刪改類系的公共方法),就對一個軟件架構的影響程度而言,不亞于俄羅斯對烏克蘭天然氣漲價給歐洲帶來的振憾,有可能帶來多米諾骨牌效應。 當方法不僅僅只是一個而是多個類系的公共行為的抽象時,我們就必須把配角方法升格為主角,讓它來支配相關類系,做法是將公共方法接口獨立出來,單獨定義成接口(interface),然后由相關類系一一實現,這時我們可以把其稱為方法的類。所有外界與其關系不再建立在抽象類而是建立在接口之上,如圖7-2。在定義接口的時候,注意不要讓其過度臃腫,一個類對另外一個類的依賴性應當是建立在最小接口上。復雜的接口可以通過接口的多重繼承或委托來分離。
之所以一步步地把方法從配角升格為主角,是因為我們希望將
需求中不穩定的成分隔離出來,用相對穩定的成分作為框架來構造系統。而一般概念的生存周期要遠遠大于特殊概念,如:職位>總裁>方興東,所以要依賴于抽象而不要依賴于具體,即依賴倒置原則(Dependence Inversion Principle),前面談到的"開放-封閉"原則是其外延。
此外盡管方法從配角變為主角,其實現還是在該類的作用域中。有時方法更出格,委托類除了定義方法簽名和通知其開工消息外,對方法的實現完全失去控制,它甚至到上臺以后才知道今天的主角究竟是誰。這就是委托(delegate)機制。實質是類直接引用另一個類的方法,只要委托方法與受托方法接口一致,目的是徹底將方法的接口與實現分離。
class 商船{
//委托類
private int 動力;
private delegate int 阻力計算委托(); //定義委托 public void 移動(阻力計算委托 阻力){
int 作用力 = 動力 -阻力();
……
}
}
class Test{
//受托類
private int 風阻力計算(){……};
static void main(){
商船 泰坦尼克;
泰坦尼克.移動(new阻力計算委托(風阻力計算)) //委托實例
}
}
委托可以這么理解,上例中商船類為委托方張三,Test類為受托方李律師,張三(商船類)稱我要告王五(阻力計算委托),李律師胸脯一拍:沒問題,這事我按民事訴訟程序(風阻力計算方法)來辦。
原文轉自:http://www.kjueaiud.com