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