第八章.设计原则
模擬是避免做傻事的最佳方式。
到目前為止我們一直致力于應(yīng)用程序編碼之前的事情上,如收集需求、分析、編寫功能列表、繪制用例圖等。當然,在某些地方真的必須編寫一些代碼,那是設(shè)計原則真正開始產(chǎn)生作用的地方。
設(shè)計原則:是能被應(yīng)用到設(shè)計或編寫程序代碼中的工具或技術(shù),讓程序代碼更可維護、根具靈活性或者更易擴展。
OO原則:
1.封裝變化之物
2.對接口編程,而不是對實現(xiàn)
3.應(yīng)用程序中的每一個類只有一個改變的理由
4.類是關(guān)于行為與功能的。
第一個設(shè)計原則:
開閉原則(OCP, Open-Closed Principle)
OCP允許改變(allowing change),但是以不需要修改現(xiàn)有程序代碼的方式進行。即代碼易擴展,但是擴展的時候不能修改原有的代碼。
OCP:類應(yīng)該允許為擴展而開放,禁止為修改而關(guān)閉(closed for modification)
OCP是封裝(encapsulation)與抽象化(abstraction)的結(jié)合。將保持不變的行為抽取到基類中,然后將程序代碼鎖住以禁止修改。當需要新的或不同的行為時,你的子類會通過擴展基類來處理這項改變。這是封裝著力的地方:你正在封裝變化之物(子類中的行為),將它與不變之物(基類中的共同行為)分開。
運用OCP的唯一方法是擴展其他類嗎?
不,只要你的程序代碼禁止為修改而關(guān)閉,但允許為擴展而開放,就是在運用OCP。例如,在類中有一些private(私有)方法,那些方法便是禁止為修改而關(guān)閉——沒有其他程序代碼能弄亂它們,但接著你可以增加一些以不同方式調(diào)用這些private方法的public方法。你正在擴展這些private方法的public方法的行為,而無需改變它們。這是一個OCP運作的另一個例子。
第二個設(shè)計原則:
不自我重復原則(DRY,Don't Repeat Yourself Principle)
DRY:通過將共同之物抽取出來并置于單一地方來避免重復的程序代碼。
DRY關(guān)系到讓系統(tǒng)中每一個信息與行為的片段都保存在單一、合理的地方。
第三個設(shè)計原則:
單一職責原則(SRP,Single Responsibility Principle)
系統(tǒng)里的每一個對象應(yīng)該具有單一職責,所有對象的服務(wù)都應(yīng)該聚焦在實現(xiàn)該職責上。
當你的每一個對象都只有一個改變的理由時,你已經(jīng)正確的實現(xiàn)單一職責原則。
SRP和DRY聽起來蠻像的,它們是相關(guān)的,DRY是關(guān)于把一個功能片段放在單一地方,如一個類;而SRP是關(guān)于確認一個類只做一件事,而且把事情做好。
在良好的應(yīng)用程序里,一個類只做一件事且把事情做好,并且沒有其他類共同分擔該行為。
讓每一個類只做一件事,是不是有點限制?
不,要知道,類所做的那一件事可以是相當大的一件事。如,棋盤游戲系統(tǒng)框架中Board類完成了很多不同的小任務(wù),但全都關(guān)系到同一件大事:處理游戲里的棋盤,而那是Board類所做的一切,所以那是使用SRP的好例子。
使用SRP有助于讓類保持較小,因為它們只做一件事,對嗎?
不,SRP通常會讓你的類更大。因為你不把功能分散到許多類中,往往會放更多的東西到類中。使用SRP通常導致較少的類,而這一般會讓你的整個應(yīng)用程序在管理和維護上簡單得多。
SRP聽起來像內(nèi)聚力(cohesion),兩者有什么關(guān)系?
內(nèi)聚力是SRP的另一個名稱,假如你在編寫具有高度內(nèi)聚性的軟件,就表示你在正確的運用SRP。
第四個設(shè)計原則:
Liskov替換原則(LSP,Liskov Substitution Principle)
Liskov替換原則:子類型(subtype)必須能夠替換其基類型(base type)。
LSP完全關(guān)系到設(shè)計良好的繼承。當你從一個基類繼承下來時,你必須能用你的子類替換該基類且不會把事情弄糟,否則,你就錯誤的使用了繼承。
誤用繼承的程序代碼是難以理解的。
使用繼承時,你的子類會從它的父類獲得所有的方法,即使你并不想要那些方法。假如你錯誤的使用繼承,將會得到許多你不想要的方法,因為它們可能另你的子類不合理。
除了繼承之外,還有什么好的方法?
將功能委托給其他類。
委托:是將特定工作的責任委派給另一個類或方法。它是繼承的幾個替代做法之一。
何時使用委托?
委托最好在你想要使用另一個類的功能時使用,依照原樣,完全沒有改變其行為。
假如你需要使用另一個類的功能性,但不想改變該功能性,考慮以委托代替繼承。
組合:將來自其他多個類的行為集合起來。
何時使用組合?
當你想要使用由接口所定義的行為,并且從該接口的種種實現(xiàn)中進行選擇是,組合是最具有威力的,不論是在編譯期間還是在運行時。
組合讓你使用來自一組其他類的行為,并且可以在運行時切換該行為。
若對象由其他對象組成,當擁有對象(owning object)被銷毀時,被擁有對象(即組合的一部分)也跟著消失。
在組合中,由其他行為所組成的對象擁有那些行為。當對象被摧毀時,其所有行為也被摧毀。組合中的行為不存在于組合本身以外。
聚合:當一個類被用作另一個類的一部分時,但仍然可以存在于該類之外。
參考資料:
組合與聚合:http://blog.csdn.net/llbupt/article/details/6618210
組合與聚合:https://zhidao.baidu.com/question/646643373466159045.html
組合與聚合:http://blog.csdn.net/qq_31655965/article/details/54645220
組合與聚合:http://forrest420.iteye.com/blog/1040271
轉(zhuǎn)載于:https://www.cnblogs.com/lanshanxiao/p/7211502.html
總結(jié)
- 上一篇: C#事件记录
- 下一篇: MyBatis Generator模板