C#動靜結合編程之二: 兩種哲學

來源:互聯網
上載者:User

在本系列的上一篇中,談到了介面和委託文法約束強度的比較,我的結論是介面的文法約束要強於委託。這個話題得到了不少朋友的關注和討論。對此,我在綜合反饋,查閱資料,加上自己的理解的基礎上對介面和委託的關係進行一個小小的總結,並藉此推動本篇的介紹。

一方面,從OO角度看,介面和委託是實現多態性的兩種手段;另一方面,從軟體設計角度看,介面和委託是將規範與實現分開從而面向抽象編程的兩種手段。因此,就存在的意義而言,介面和委託有著重要的聯絡。雖然委託不能覆蓋介面所有的功能,關於文法約束強度的比較沒有全面的說服力,但我們明顯能體會到委託比介面更加靈活。

兩種哲學

這裡尤其值得注意的是介面和委託所代表的兩種哲學:繼承哲學和鴨子哲學。繼承哲學關注對象繼承結構,即“你繼承什麼你就是什麼”;鴨子哲學關注對象的性質,即“你能做什麼你就是什麼”。PS:“鴨子哲學”的名稱來源於Duck Typing的相關論述“如果一隻動物,走起來像鴨子,叫起來像鴨子,那我可以把它當鴨子”。

需要強調的是,繼承哲學不止體現在介面上,鴨子哲學也不只體現在委託上。而兩種哲學,也各有優勢,各有適用場合,沒有高下,這裡只為看清它們的差別,以靈活運用。

讓我們先來看一個例子:對體育進行領域建模,這裡我們只關注教練和隊員的建模。

從繼承到組合

按繼承哲學的方法論”是什麼就應該繼承什麼”,我們很容易想到定義IPlayer,ICoach等介面,讓隊員繼承(實現)IPlayer,讓教練繼承ICoach。一般情況下,這本來沒有什麼問題,但考慮到對象生命週期這個關鍵因素,情況就可能有所不同。比如,我們知道劉國梁原來是乒乓球隊員,後來當上了教練,要表達劉國梁從隊員到教練的轉變就不那麼容易。因為,C#是靜態類型語言,繼承關係是在編譯時間確定的,無法在運行時刪除繼承關係(劉國梁退役),也無法在運行時增加繼承關係(劉國梁當教練)。如果要勉強認為隊員劉國梁和教練劉國梁是兩個對象也是可以的,不過這必然影響領域模型的表達是否自然。

很多有經驗的朋友可能已經意識到:C#中繼承是很強的靜態約束,如果領域模型足夠複雜,在對象生命週期內,其具有的行為可能會發生變化,那麼必須慎用繼承。

用組合代替繼承是增加模型靈活性的常見手段,一般方法是將行為抽象為行為類/介面/委託,比如:定義IPlay,ITeach行為介面,並為對象增加行為屬性Play和Teach。雖然組合關係在C#中也是無法動態增加和刪除的,但可以採取折衷的方式,具體到上面的例子,對象整個生命週期內都必須具有Play和Teach的行為屬性,並且通過拋出運行時異常來表達對象還不具備某種行為。

繼承到組合的轉變在一定程度上顯示了鴨子哲學的靈活性。實際上,所謂“行為”正是“能做什麼”。通過上面的例子不難發現,組合關係通過把焦點從“繼承什麼”轉移到“能做什麼”獲得了更大的靈活性。這個轉變一點兒不勉強,很自然,很符合領域的本質。雖然,C#中組合關係也是靜態,但已經比繼承具有了更多的動態元素,而動態和靜態本身沒有優劣,必鬚根據領域建模需要把握分寸。

後續

下一篇,我將重點介紹鴨子哲學更純正的體現:Duck Typing,敬請關注!

 

修改曆史:

1. 2009-03-16 初版

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.