在最開始,先重復(fù)一下第一篇的內(nèi)容,這個(gè)系列是寫我們?nèi)绾蝸?lái)組織代碼,如何提高可擴(kuò)展性和維護(hù)性的,并不涉及到網(wǎng)絡(luò)拓補(bǔ)結(jié)構(gòu)或各類中間件的使用。
首先,提一提面向?qū)ο笤O(shè)計(jì)的五大原則:SOLID。
SOLID原則
SOLID都是些什么呢?
SRP, Single responsibility principle,單一職責(zé)。一個(gè)類只能有一個(gè)職責(zé),如果這個(gè)類需要被修改,那只能是某一個(gè)需求更改導(dǎo)致的(僅此一個(gè),沒(méi)有更多的)。例如,book類里面有一個(gè)print的函數(shù),當(dāng)我們修改book類的書名時(shí),我們需要改book類,當(dāng)我們把book的打印從打印到A4改成打印成6寸時(shí),也需要修改此類,這就違背了SRP原則。
OCP, Open/closed principle,開閉原則,Open for extension, but closed for modification
LSP, Liskov substitution principle,父類能夠被子類無(wú)憂的替代,不必?fù)?dān)心產(chǎn)生副作用。
ISP, Interface segregation principle,如果一個(gè)接口能夠被拆分成多個(gè)接口,那就不該用這個(gè)通用的接口來(lái)呈現(xiàn)。
DIP, Dependency Inversion principle,依賴于抽象,而不依賴與具體的實(shí)現(xiàn)。
今天先從SRP和DI開始。
單一職責(zé)
它的定義上面已經(jīng)講過(guò)了。
這一條是用來(lái)幫助我們創(chuàng)建更為松耦合和模塊化的程序,因?yàn)槊糠N不同的行為我們都封裝到一個(gè)新的類或?qū)ο罄锩嫒チ?。未?lái)要增加新的行為或特性,新增的內(nèi)容也會(huì)增加新的對(duì)象里面,而不是把這些行為加到原來(lái)的對(duì)象上去。
這樣做的好處是更安全,更不容易出錯(cuò),因?yàn)橐郧暗念惪赡苁呛卸喾N多樣的依賴關(guān)系的,但新增加的類卻沒(méi)有那些依賴在里面。所以我們可以放心的修改系統(tǒng)行為,不必?fù)?dān)心修改帶來(lái)的副作用。
在分層結(jié)構(gòu)中,這個(gè)思想也有體現(xiàn)。我們的UI/Presentation層專管UI的顯示,logic層專攻業(yè)務(wù)邏輯,數(shù)據(jù)訪問(wèn)層只做數(shù)據(jù)訪問(wèn)相關(guān)內(nèi)容。其實(shí),都是同樣的道理。
如果SRP思想貫穿了你的整個(gè)程序,你的邏輯層里的某一個(gè)服務(wù)是不是就成了微服務(wù),一個(gè)微服務(wù)只有一個(gè)單一的職責(zé),你要給你的程序增加功能,那再加一個(gè)微服務(wù)即可(切忌在已有的微服務(wù)上添加)
依賴反轉(zhuǎn)(Dependency Inversion)
應(yīng)用程序內(nèi)部的依賴不應(yīng)該依賴于具體的實(shí)現(xiàn),應(yīng)該依賴于抽象。
也是五大原則之一。
很多應(yīng)用的依賴是在編譯期就確定了依賴的順序,就如同模塊A調(diào)用了模塊B的一個(gè)函數(shù),剛好這個(gè)模塊B內(nèi)的函數(shù)又調(diào)用了模塊C的某個(gè)函數(shù),于是,A就依賴B,B依賴于C。
應(yīng)用了DIP之后,就像這個(gè)樣子:
可以看到,ClassA不再依賴于Class B,轉(zhuǎn)而依賴InterfaceB,ClassB也不再依賴于Class C,轉(zhuǎn)變成Interface B依賴于Interface C。
ClassA現(xiàn)在依賴的是B的抽象(即Interface B