這么糟糕的代碼,真的是我以前寫(xiě)的嗎?
- 很多程序員不知道怎么組織代碼、怎么提升效率、怎么提高代碼的可維護(hù)性、可重用性、可擴(kuò)展性、靈活性,寫(xiě)出來(lái)的代碼一團(tuán)糟,但這樣一團(tuán)糟的代碼居然能正常運(yùn)行。
這樣的代碼經(jīng)歷,你是否也似曾相識(shí)?
身邊好多程序員都會(huì)有這樣的一個(gè)經(jīng)歷,過(guò)個(gè)一年半載再去查看曾經(jīng)寫(xiě)下的代碼時(shí),很吃驚的在想,這么糟糕的代碼,真的是我以前寫(xiě)的嗎?我居然能寫(xiě)出這么糟糕的代碼!
而對(duì)于還在維護(hù)的代碼,此時(shí),會(huì)萌生一種去重構(gòu)的想法,或者會(huì)有一種更好的方式去實(shí)現(xiàn)。此時(shí),你與代碼的愛(ài)恨情仇已經(jīng)開(kāi)始了 …
本片主要從六大基本原則說(shuō)起,作為設(shè)計(jì)模式的引子,敘述六大基本原則和設(shè)計(jì)模式的關(guān)系,后續(xù)會(huì)一篇一個(gè)設(shè)計(jì)模式,詳細(xì)介紹設(shè)計(jì)模式與日常開(kāi)發(fā)。
基本的規(guī)范和約束
對(duì)于基本的規(guī)范和約束,我相信每個(gè)合格的團(tuán)隊(duì)都會(huì)有一套自己的玩意,一方面統(tǒng)一標(biāo)準(zhǔn),增加可讀性和可維護(hù)性,另一方面也方便離職后出現(xiàn) bug,后來(lái)者也能更快的去定位并解決問(wèn)題。
雜亂無(wú)章的代碼實(shí)現(xiàn)一個(gè)大功能,對(duì)于后來(lái)者去維護(hù),無(wú)疑會(huì)親切的問(wèn)候各路祖宗。一個(gè)好的編碼習(xí)慣,屬于一個(gè)合格程序員的自我修養(yǎng),于己于人,百利而無(wú)一害。
對(duì)于開(kāi)發(fā)中的規(guī)范和約束,第一個(gè)要說(shuō)的就是命名。
這五年多的工作,和形形色色的人合作過(guò),記得最多的時(shí)候,我曾同時(shí)期開(kāi)發(fā)和維護(hù)五個(gè)項(xiàng)目,業(yè)余時(shí)間,也曾和各路英雄好漢互相合作、互相學(xué)習(xí)和共同進(jìn)步,在這個(gè)過(guò)程中,最讓我覺(jué)得頭疼的就是一些命名的不規(guī)范。
不規(guī)范的樣式有很多,各種奇怪的命名都有。我曾看到過(guò)這樣一串命名,其中有兩個(gè)功能,一個(gè)叫做專(zhuān)欄詳情,一個(gè)叫做專(zhuān)欄留言,命名卻是 “ZhuanLaiDetalActivity” 和 “ZhuanLaiLiuYanActivity”,看得我很懵。
這樣的命名,就問(wèn)你怕不怕!對(duì)于這樣的命名都怕了,那真沒(méi)見(jiàn)過(guò)世面,這個(gè)至少還能看出個(gè)大概,之前看到過(guò)一些漢語(yǔ)拼音的縮寫(xiě),比如動(dòng)檢證命名為 djz,這個(gè)看起來(lái)才更懵了。
對(duì)于拼音命名,這里說(shuō)一點(diǎn)不知道會(huì)不會(huì)被噴,遇到過(guò)一些朋友總是喜歡拼音命名,漢語(yǔ)拼音是中華民族推動(dòng)漢文化的偉大創(chuàng)舉,但是在編程的時(shí)候用拼音,真的覺(jué)得好 low。
即使再牛逼的技術(shù)作支撐,寫(xiě)出來(lái)的代碼也像小學(xué)生的作品,這里沒(méi)有看不起漢語(yǔ)拼音的意思,只是發(fā)表下內(nèi)心的一些想法。
建議:大駝峰、小駝峰或者下劃線(xiàn)命名都可以,如果沒(méi)有一個(gè)統(tǒng)一的標(biāo)準(zhǔn),可以參考《阿里巴巴 Java 開(kāi)發(fā)手冊(cè)》,對(duì)于剛?cè)胄械呐笥?,更?yīng)該從命名抓起,對(duì)于以后的成長(zhǎng)有很大的幫助。
開(kāi)發(fā)手冊(cè)下載地址:https://pan.baidu.com/s/1mjZxvSW。
再者要強(qiáng)調(diào)的就是注釋。很多人也許覺(jué)得注釋是越多越好,之前也在書(shū)上看到過(guò)提倡多加注釋?zhuān)矣X(jué)得不然,有些時(shí)候注釋給我們?cè)黾恿撕芏嘭?fù)擔(dān)和誤解。
上次 review 的時(shí)候發(fā)現(xiàn),一些同事 copy 我的一些代碼的時(shí)候,其實(shí)是想做另一個(gè)功能,只是想把一些代碼拷貝過(guò)去然后大修改(我不喜歡重復(fù)造輪子,對(duì)于相似的一些功能,最好做的靈活一點(diǎn),提高代碼的可重用性和靈活性)。
其實(shí)可以重用的地方很少,搞不明白為啥不自己寫(xiě)那么幾行代碼,這都不是事,讓我很懵逼的是他們把我的備注和作者也拷貝過(guò)去了,當(dāng)我進(jìn)入那個(gè)類(lèi)的時(shí)候,發(fā)現(xiàn)作者是我,去 git 查看歷史提交,完全沒(méi)我啥事,而且功能描述和此類(lèi)完全不相關(guān) …
對(duì)于注釋?zhuān)€有一點(diǎn)要說(shuō)的就是一些多余的注釋?zhuān)@個(gè)叫需要和命名相結(jié)合,好的命名規(guī)范,可以省略好多不必要注釋?zhuān)热? login、register,再加上登錄、注冊(cè)的注釋?zhuān)耆珱](méi)必要。
良好的習(xí)慣,可以給我們開(kāi)發(fā)帶來(lái)很多便捷,但有些喜歡 textview1、textview2 命名的,這些就算加了注釋?zhuān)认挛挠玫降臅r(shí)候,看了也是一群羊駝在奔跑,上下奔騰的那種。
- for (int i = 0; i < j; i++) {
- // TODO
- }
對(duì)于這樣的代碼,可能很多人會(huì)覺(jué)得很正常,也會(huì)有部分人會(huì)把責(zé)任歸咎于譚浩強(qiáng)老師,是的,譚老的書(shū)中問(wèn)題確實(shí)很多,但這不是寫(xiě)這種代碼的理由。
日常開(kāi)發(fā)中,還有平時(shí)維護(hù)別人代碼的同時(shí),總會(huì)去調(diào)試 for 語(yǔ)句,難道不覺(jué)得這樣的代碼很糟糕,看得有點(diǎn)懵嗎?就算加了注釋?zhuān)€是一坨一坨的。
因?yàn)槊總€(gè)團(tuán)隊(duì)有自己的規(guī)范和約束,大的公司,會(huì)有一套自己的規(guī)范,統(tǒng)一于各個(gè)團(tuán)隊(duì),不同的語(yǔ)言也有不同的約束,如果日后有時(shí)間,會(huì)專(zhuān)門(mén)寫(xiě)一篇詳細(xì)的約束與規(guī)范的 blog 贈(zèng)送。
對(duì)于這塊,想寫(xiě)的東西真的好多好多,比如 case 后面的亂用,1、2、3 總是讓人費(fèi)解,比如必要的常量替代變量,比如線(xiàn)程池取代線(xiàn)程,比如必要的地方使用單例,東西真的好多好多,不再比如下去了,今天就先說(shuō)明兩條重點(diǎn),命名和注釋。
建議:合理使用注釋?zhuān)瑢?duì)于新手在學(xué)習(xí)期間,在陌生的代碼和不清晰的邏輯上,盡可能多一點(diǎn)注釋?zhuān)阌诶斫?,?duì)于老鳥(niǎo),盡可能規(guī)范的命名。
通過(guò)命名達(dá)到注釋的效果,但是對(duì)于邏輯復(fù)雜或者操作狀態(tài)太多的時(shí)候,必要的注釋還是很重要的,減小維護(hù)成本。
一些應(yīng)該熟知的編程思想
一個(gè)程序員用在寫(xiě)程序上的時(shí)間大概占他的工作時(shí)間的 10-20%,大部分的程序員每天大約能寫(xiě)出 10-12 行的能進(jìn)入最終的產(chǎn)品的代碼——不管他的技術(shù)水平有多高。
好的程序員花去 90% 的時(shí)間在思考、研究和實(shí)驗(yàn),來(lái)找出最優(yōu)方案。差的程序員花去 90% 的時(shí)間在調(diào)試問(wèn)題程序、盲目的修改程序,期望某種寫(xiě)法能可行。
對(duì)于一個(gè)優(yōu)秀的程序員來(lái)說(shuō),邏輯才是最重要的,他們?cè)敢饣ǜ嗟臅r(shí)間做思考,這樣做的同時(shí),就是更少 bug 會(huì)出現(xiàn),甚至可以把 bug 率降到很低。
我并不是很優(yōu)秀的開(kāi)發(fā)者,但這些年依然有這么一個(gè)習(xí)慣,對(duì)于復(fù)雜或者多樣的功能,總會(huì)先理清思路,先列舉出會(huì)有哪些操作,哪些地方是 bug 的雷區(qū)應(yīng)該多注意,我也經(jīng)常會(huì)和隊(duì)友提起,一圖勝千言,理清思路再下手,事半功倍。
不管業(yè)務(wù)邏輯是否復(fù)雜,上去就是干,發(fā)現(xiàn)有何不妥的再去修改,發(fā)現(xiàn)漏掉的再去添加,這樣導(dǎo)致代碼總是一坨一坨的堆在那里,經(jīng)過(guò)多次的修改,已經(jīng)面目全非,對(duì)于維護(hù)的人來(lái)說(shuō),更是苦不堪言。
在此,筆者也建議讀者朋友,不妨試一試先繪圖在動(dòng)手,把一個(gè)模塊繼續(xù)拆解成一個(gè)個(gè)接口,通過(guò)實(shí)現(xiàn)接口去實(shí)現(xiàn)這個(gè)模塊,做到面向接口編程,這樣可維護(hù)性會(huì)提升好多 … …
對(duì)于模塊與模塊之間的通信,不應(yīng)該是類(lèi)與類(lèi)之間的關(guān)聯(lián),而是通過(guò)抽象去實(shí)現(xiàn)交互,抽象不應(yīng)該依賴(lài)于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴(lài)于抽象,這話(huà)比較繞口,說(shuō)白了,就是面向接口編程,而不是面向?qū)崿F(xiàn)編程。
這樣做的好處就是,將來(lái)你要把這個(gè)被調(diào)用的類(lèi)換成一個(gè)別的實(shí)現(xiàn)類(lèi)時(shí),你就不用去把調(diào)用過(guò)它的類(lèi)一個(gè)個(gè)改掉了,因?yàn)樗鼈冋{(diào)的是接口,接口沒(méi)變,在配置里把接口的實(shí)現(xiàn)類(lèi)換成新的類(lèi),就全部都替換掉了。
類(lèi)之間的耦合越弱,越有利于復(fù)用,一個(gè)處在弱耦合的類(lèi)被修改,不會(huì)對(duì)有關(guān)系的類(lèi)引起波及。
建議:理清思路再下手,事半功倍。開(kāi)發(fā)過(guò)程中,不妨先定義好接口,通過(guò)實(shí)現(xiàn)接口去完成模塊的開(kāi)發(fā),盡可能的減小 bug 率,寫(xiě)出更加優(yōu)質(zhì)的代碼。
技術(shù)能力的提高,從代碼上的體現(xiàn)主要在于 “高內(nèi)聚、低耦合”,因?yàn)檫@些思想衍生出許多開(kāi)發(fā)模式,比如現(xiàn)在比較流行的 MVC、MVP、MVVM 等。
版本迭代與重構(gòu)
我們?cè)谧鋈魏蜗到y(tǒng)的時(shí)候,都不要指望系統(tǒng)一開(kāi)始時(shí)需求確定,就再也不會(huì)變化,這是不現(xiàn)實(shí)也不科學(xué)的想法,而既然需求是一定會(huì)變化的,那么如何在面對(duì)需求的變化時(shí),設(shè)計(jì)軟件的可以相對(duì)容易修改,不至于說(shuō),新需求一來(lái),就要把整個(gè)程序推倒重來(lái)。
相信很多朋友都遇到過(guò),原本一個(gè)很普通的需求,在經(jīng)歷過(guò) N 次迭代和修改后,已經(jīng)形成一個(gè)龐大的功能,隨著版本的不斷迭代,維護(hù)起來(lái)的成本也隨著越來(lái)越大,這樣就形成了一種惡性循環(huán),重構(gòu)代碼即將登上歷史舞臺(tái)。
不可否認(rèn),從維護(hù)成本上看,重構(gòu)確實(shí)是一個(gè)很不錯(cuò)的方案,重構(gòu)的成本比原基礎(chǔ)維護(hù)的成本更小,也更方便以后的維護(hù)。有些公司甚至在多次版本迭代后,直接把整個(gè)項(xiàng)目推到重構(gòu),這樣的事情不僅僅發(fā)生在小公司,在一些大公司,也是會(huì)發(fā)生多次。
從技術(shù)上來(lái)說(shuō),重構(gòu)復(fù)雜代碼時(shí)要做三件事:理解舊代碼、分解舊代碼、構(gòu)建新代碼。
而待重構(gòu)的舊代碼往往難以理解,尤其是在多次迭代且多人經(jīng)手的模塊;模塊之間過(guò)度耦合導(dǎo)致?tīng)恳话l(fā)而動(dòng)全身,不易控制影響范圍;舊代碼不易測(cè)試導(dǎo)致無(wú)法保證新代碼的正確性,尤其是在產(chǎn)品文檔不全的時(shí)候。
這是上次 review 時(shí)候發(fā)現(xiàn)的一段代碼,先不說(shuō)常量使用的不規(guī)范,這是經(jīng)過(guò)一次次產(chǎn)品迭代后的結(jié)果,但這不是借口,造了這么多次輪子,真不應(yīng)該。做為代碼可重用性的反面教材,此處體現(xiàn)的淋漓盡致,如果有更多的狀態(tài),此處必然還是會(huì)重復(fù)多次 …
建議:重構(gòu),并不是萬(wàn)能的,重構(gòu)后的代碼,當(dāng)再次經(jīng)歷后續(xù)幾個(gè)版本修改后,代碼又顯的雜亂無(wú)章,那一坨坨代碼總是在不斷的重演。
既然無(wú)法確定需求日后是否會(huì)修改,那我們只能通過(guò)提高代碼質(zhì)量來(lái)應(yīng)對(duì),以不變應(yīng)萬(wàn)變,合理設(shè)計(jì)接口,每次更改需求時(shí)多思考,對(duì)于多次使用的代碼進(jìn)行封裝提取,盡可能少的改動(dòng)既有的邏輯。
設(shè)計(jì)模式的重要性
會(huì)建筑設(shè)計(jì)的是建筑工程師,不會(huì)建筑設(shè)計(jì)的是搬磚的。
前面已經(jīng)說(shuō)了很多,現(xiàn)在直接說(shuō)一下設(shè)計(jì)模式的重要性,提到設(shè)計(jì)模式,就必須要提到六大基本原則和架構(gòu)設(shè)計(jì),提到架構(gòu)設(shè)計(jì),設(shè)計(jì)模式的重要性便可想而知。
首先,六大基本原則還是有點(diǎn)爭(zhēng)議的,我之前看到的書(shū)籍中,一般都是單一職責(zé)原則、迪米特法則、里氏替換原則、開(kāi)閉原則、依賴(lài)倒置原則和接口隔離原則。
但我最近在一些帖子上看到,有一種說(shuō)法是沒(méi)有接口隔離原則,而是合成 / 聚合復(fù)用原則,為了不影響之前的準(zhǔn)備,合成 / 聚合復(fù)用原則會(huì)單獨(dú)拿出來(lái)說(shuō)一下。
六大基本原則,它是整個(gè)架構(gòu)設(shè)計(jì)的靈魂,是架構(gòu)設(shè)計(jì)的一種指導(dǎo)思想,而設(shè)計(jì)模式是架構(gòu)設(shè)計(jì)的一種具體設(shè)計(jì)技巧,是架構(gòu)設(shè)計(jì)的具體實(shí)踐。
先從架構(gòu)設(shè)計(jì)說(shuō)起,對(duì)于架構(gòu)設(shè)計(jì),主要體現(xiàn)在抽象能力,抽象能力又依賴(lài)于架構(gòu)者編碼的閱歷、功能的拆解和理解、邏輯的嚴(yán)密性。
做架構(gòu)設(shè)計(jì)應(yīng)該盡可能且更全面的考慮問(wèn)題,盡可能做好代碼的包容性,海納百川,有容乃大之勢(shì),這是架構(gòu)設(shè)計(jì)者應(yīng)該具備的基本條件。
考慮的問(wèn)題越周全,包容性越強(qiáng),則工作難度越大,給自己造成的障礙也越多。合理的將這些細(xì)節(jié)問(wèn)題進(jìn)行抽象,并提出解決方案,抽象程度越高,解決方案越合理,這才是架構(gòu)者的價(jià)值所在。
從具體的需求,到代碼實(shí)現(xiàn),再到具體的產(chǎn)品。架構(gòu)設(shè)計(jì)的目的無(wú)外乎系統(tǒng)的復(fù)用性、擴(kuò)展性與穩(wěn)定性,具體的東西是無(wú)法很好地體現(xiàn)這些特性的,只有抽象的事物才能最好的體現(xiàn)。
在架構(gòu)設(shè)計(jì)的過(guò)程中,單一職責(zé)原則告訴我們應(yīng)該更好的體現(xiàn)高內(nèi)聚、低耦合,這個(gè)類(lèi)是用來(lái)數(shù)據(jù)請(qǐng)求的,就別放一些解析 json 的方法,如果這個(gè)類(lèi)是用來(lái)圖片加載的,view 的注解請(qǐng)隔離開(kāi),做到一個(gè)類(lèi)只負(fù)責(zé)一個(gè)職責(zé),只有一個(gè)引起變化的原因。
如果一個(gè)類(lèi)承擔(dān)的職責(zé)越多,就等于把這些職責(zé)耦合到一起,會(huì)帶來(lái)一些不必要的維護(hù)成本。從大的角度來(lái)說(shuō),MVP 和 MVC 模式都是單一職責(zé)原則的體現(xiàn),model-視圖-控制相隔離,各司其職。
迪米特法則指導(dǎo)我們?nèi)绻麅蓚€(gè)類(lèi)不必彼此直接通信,那么這兩個(gè)類(lèi)就不應(yīng)當(dāng)發(fā)生直接的相互作用。如果其中一個(gè)類(lèi)需要調(diào)用另一個(gè)類(lèi)的某一個(gè)方法時(shí),可以通過(guò)第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用。
類(lèi)之間的耦合越弱,就越有利于復(fù)用,一個(gè)處在弱耦合的類(lèi)被修改,不會(huì)對(duì)有關(guān)系的類(lèi)造成波及。主要是強(qiáng)調(diào)了類(lèi)之間的松耦合。
對(duì)于里氏替換原則,或許很多人沒(méi)聽(tīng)過(guò)這個(gè)名詞,但是在實(shí)際開(kāi)發(fā)過(guò)程中卻無(wú)時(shí)無(wú)刻不在使用,其實(shí)很簡(jiǎn)單,子類(lèi)型必須能夠替換掉它們的父類(lèi)型。
舉個(gè)簡(jiǎn)單的例子,“List< String> list = new ArrayList<>();”,這么做的好處其實(shí)很簡(jiǎn)單,比如有一天 ArrayList 滿(mǎn)足不了需求,需要改用 LinkedList,只需要把 ArrayList 替換成 LinkedList,而不是把全局的 list 對(duì)象都改一遍,提高了可維護(hù)性。
開(kāi)閉原則是面向?qū)ο笤瓌t的核心,有兩部分組成,對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。軟件需求總是會(huì)變化的,對(duì)軟件設(shè)計(jì)人員來(lái)說(shuō),必須在不需要對(duì)原有系統(tǒng)進(jìn)行修改的情況下,實(shí)現(xiàn)靈活的系統(tǒng)擴(kuò)展。
對(duì)擴(kuò)展開(kāi)放,就是對(duì)抽象編程,而不是具體編程,因?yàn)槌橄笙鄬?duì)穩(wěn)定,通過(guò)接口或者抽象類(lèi)約束擴(kuò)展,對(duì)擴(kuò)展進(jìn)行邊界限定,不允許出現(xiàn)在接口或抽象類(lèi)中不存在的 public 方法。
讓類(lèi)依賴(lài)于固定的抽象,所以,對(duì)修改是關(guān)閉的。這是建立在繼承和多態(tài)的基礎(chǔ)上,可以實(shí)現(xiàn)對(duì)抽象類(lèi)的繼承,通過(guò)覆蓋其方法來(lái)擴(kuò)展方法。
依賴(lài)倒置原則指的是依賴(lài)于抽象而不是依賴(lài)于具體實(shí)現(xiàn),這一塊在上述已經(jīng)說(shuō)過(guò),其實(shí)就是面向接口編程而不是面向?qū)崿F(xiàn)編程,這樣做的好處就是解決耦合。
一般情況下抽象的變化概率很小,讓用戶(hù)程序依賴(lài)于抽象,實(shí)現(xiàn)的細(xì)節(jié)也依賴(lài)于抽象。即使實(shí)現(xiàn)細(xì)節(jié)不斷變動(dòng),只要抽象不變,客戶(hù)程序就不需要變化。這大大降低了客戶(hù)程序與實(shí)現(xiàn)細(xì)節(jié)的耦合度。
接口隔離原則認(rèn)為,“使用多個(gè)專(zhuān)門(mén)的接口總比使用單一的接口要好”。
一個(gè)模塊應(yīng)該依賴(lài)它需要的接口,需要什么接口就提供什么接口,把不需要的接口剔除掉,同時(shí)也應(yīng)該遵循單一職責(zé)原則,這樣避免臃腫的接口帶來(lái)的污染,將沒(méi)有關(guān)系的接口合并在一起,形成臃腫的大接口,就是對(duì)接口的一種污染。
接口的粒度也不能太小,太小會(huì)導(dǎo)致接口額數(shù)量劇增,對(duì)開(kāi)發(fā)人員不友好;接口額粒度太大,靈活性降低,無(wú)法提供定制服務(wù),給整體項(xiàng)目帶來(lái)無(wú)法預(yù)估的風(fēng)險(xiǎn),合理的設(shè)計(jì)接口,也是一門(mén)藝術(shù)。
對(duì)于這張圖,一定存在很多的爭(zhēng)議,因?yàn)楹芏嘣O(shè)計(jì)模式都用到了多個(gè)基本原則,上圖只是對(duì)設(shè)計(jì)模式的一個(gè)比較粗糙的總結(jié)。
強(qiáng)調(diào)六大基本原則 (含有合成 / 聚合復(fù)用原則) 在設(shè)計(jì)模式中的具體體現(xiàn),同時(shí)也說(shuō)明了六大基本原則和 23 種設(shè)計(jì)模式是相輔相成的,六大基本原則作為設(shè)計(jì)模式的基石和模板,設(shè)計(jì)模式是六大基本原則運(yùn)用的靈活體現(xiàn)。
合成 / 聚合復(fù)用原則這個(gè)是存在一定爭(zhēng)議的。目前有的書(shū)中還是保留了合成 / 聚合復(fù)用原則去掉了接口隔離原則,合成 / 聚合復(fù)用原則指的是少用繼承,多用合成關(guān)系來(lái)實(shí)現(xiàn)。
合成和聚合都是對(duì)象建模關(guān)聯(lián)關(guān)系的一種,聚合表示一種弱的擁有關(guān)系,整體由部分組成,部分可以脫離整體作為一個(gè)獨(dú)立的個(gè)體存在,合成則是一種強(qiáng)的擁有關(guān)系,體現(xiàn)了嚴(yán)格的部分和整體的關(guān)系,部分和整體的生命周期一致,部分不能脫離整體。
總結(jié):六大基本原則是面向?qū)ο笏枷氲捏w現(xiàn),單一職責(zé)原則與接口隔離原則體現(xiàn)了封裝的思想,開(kāi)閉原則體現(xiàn)了對(duì)象的封裝與多態(tài),而里氏替換原則是對(duì)對(duì)象繼承的規(guī)范。
至于依賴(lài)倒置原則,則是多態(tài)與抽象思想的體現(xiàn)。在充分理解面向?qū)ο蟮幕A(chǔ)上,掌握基本的設(shè)計(jì)原則,并且能夠在項(xiàng)目設(shè)計(jì)中靈活運(yùn)用,就能夠改善我們的代碼質(zhì)量和結(jié)構(gòu)設(shè)計(jì)。
尤其能夠保證可重用性、可維護(hù)性、可擴(kuò)展性和靈活性,這也是理解和掌握設(shè)計(jì)模式必備的知識(shí)。
補(bǔ)充
對(duì)于六大基本原則,這是我們開(kāi)發(fā)都應(yīng)該熟記于心并且靈活運(yùn)用的,對(duì)于設(shè)計(jì)模式在日常開(kāi)發(fā)中的運(yùn)用,有一點(diǎn)還是要強(qiáng)調(diào)的,適合自己的才是最好的。
如果此時(shí)一個(gè)模塊是很輕量級(jí),僅僅為了使用設(shè)計(jì)模式而用設(shè)計(jì)模式,這無(wú)疑也會(huì)顯得不倫不類(lèi),使項(xiàng)目變的臃腫,同時(shí)也帶來(lái)一些不必要的維護(hù)成本(雖然維護(hù)成本很低)。
最近開(kāi)始整理資料,準(zhǔn)備寫(xiě)設(shè)計(jì)模式專(zhuān)題,主要是 MVP 爬坑與迪米特法則、framework 與開(kāi)閉原則、單例與爬坑、換膚與觀察者模式、加載列表與模板方法模式、構(gòu)造函數(shù)與建造者的對(duì)比、多個(gè)第三方登錄與命令模式,后續(xù)還會(huì)繼續(xù)完善,敬請(qǐng)期待。