.NET 设计规范--.NET约定、惯用法与模式--6.为扩展性而设计
6.1 擴展機制
6.1.1 非密封類
密封類即無法派生子類,也無法擴展。與此相反,非密封類可以派生子類進行擴展
?//string cannot be inherited from
public sealed class String{}
//TraceSource can be inherited from
public class TraceSource{}
正因為如此,如果需要既簡單有開銷不大的擴展方法,那么沒有聲明任何虛成員或保護成員的非密封類時不錯的選擇。
考慮用不包含任何虛成員或保護成員的非密封類來為框架提供擴展性,這種方法的開銷不高,用戶也喜歡。
6.1.2 保護成員
保護成員本身并不能提供任何的擴展性,但它們能夠加強派生子類這一擴展機制。
考慮將保護成員用于高級定制
要在對安全性。文檔及兼容性進行分析時,把非密封類中保護成員作為公有成員來對待
6.1.3 事件與回調函數
回調函數是一種擴展機制,它使框架能夠通過委托來調用用戶代碼,這些委托通常是作為方法的參數傳遞給框架的。
事件是一種特殊的回調函數,它為用戶提供了一致的語法,使用戶能夠非常方便的把委托提供給框架
考慮使用回調函數來讓框架能夠執行用戶提供的代碼
考慮用事件來讓用戶定制框架的行為,這樣就不需要用用戶對面向對象設計有深入了解。
要游戲使用事件,而不是簡單的回調函數,其原因在于廣大開發人員更熟悉事件,而且事件與Visual Studio的statement completion特性集成在一起。
避免在對性能要求很高的API中使用回調函數。
要理解在調用委托時可以執行任何代碼,這可能會引起安全性,正確行及兼容性的問題。
6.1.4 虛成員
與回調函數相比,虛成員的主要的缺點在于它的行為只能靜態修改(在編譯時修改),而回調函數的行為則可以動態修改(在運行時修改)。
不要使用虛成員,除非有合適的理由,同時你對設計、測試及維護虛成員的開銷有清楚的認識。
在以擴展性為 名義做決定前,請確保你完全理解了自己對擴展的需求。
考慮只有在絕對必須的時候才用虛成員提供擴展性,并使用Template Method模式。
要優先使用受保護的虛成員,而不是公有虛成員。公有虛成員應該通過調用受保護的虛成員的方式來提供擴展性。
類的公有成員應該為類的直接使用者提供正確的功能集。虛成員的設計目的是為了讓子類覆蓋。而受保護的訪問權限是一種很好的方法,可以對其使用范圍加以限制。
6.1.5 抽象(抽象類型與抽象接口)
抽象就是描述一個協定但是并不為該協定提供完整實現的類型。抽象通常實現為抽象類或接口,并帶有一些參考文檔,來描述實現該協定類型必須具備的那些語義。
不要提供抽象,除非為該抽象開發出具體實現并用到該抽象的API隊其進行過實際測試。
要在設計抽象時謹慎地選擇抽象類或是抽象接口
考慮為抽象的具體實現提供參考測試。這類測試應該告訴用于,他們是否正確實現餓了協定。
6.2 基類
? 我們把基類限定為這樣的類:其設計目的不是為了直接使用或提供常用的抽象,而是為了讓其他類通過繼承類重用它的默認實現。
考慮使用基類為抽象類,即使他們并不包含任何抽象成員。這能夠清楚地告訴用戶,設計這些類的目的的完全是為了讓用戶從他們派生自己的子類。
考慮把基類與用于主要場景的類型分開,放到單獨的名字空間中。根據定義,基類是為了高級擴展而設計的,因此大多數用戶對它們并不感興趣。
避免在命名基類時使用“Base”后綴,如果該類會用于公用API。
6.3 密封
密封是一種阻止擴展的有效機制。開發人員既可以密封整個類,也可以密封類中的單個成員。密封整個類使用戶不能自該類繼承,而密封一個成員則使用戶不能覆蓋該成員。
不要把類密封起來,除非有恰當的理由。
把類密封起來的恰當理由包括:
類為靜態類
類的保護成員保存了需要高度保密的機密信息
類繼承了許多虛成員,把這些成員一個一個都密封起來的代價太高,還不如把整個類都密封起來。
類時attribute,需要能再運行的時候快速查找
不要在密封類中聲明保護成員或虛成員
考慮在覆蓋成員時將其密封
?
轉載于:https://www.cnblogs.com/lufangtao/archive/2012/04/10/2441276.html
總結
以上是生活随笔為你收集整理的.NET 设计规范--.NET约定、惯用法与模式--6.为扩展性而设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 让IE7/8使用CSS中first-ch
- 下一篇: 分享一个超棒的在线jQuery mobi