送你一份設(shè)計(jì)模式入坑指南!寫(xiě)出詩(shī)一樣的代碼

寫(xiě)在前面
今天開(kāi)通了「設(shè)計(jì)模式」系列,和大家一起學(xué)習(xí)設(shè)計(jì)模式,加深我自己記憶的同時(shí),也希望能給大家?guī)?lái)一些幫助,畢竟只有我的文章大家都能看懂,才證明我真正學(xué)廢(會(huì))了。
什么是設(shè)計(jì)模式?
設(shè)計(jì)模式(Design Pattern):是前輩們對(duì)代碼開(kāi)發(fā)經(jīng)驗(yàn)的總結(jié),是解決特定問(wèn)題的一系列套路。注意,它并不是語(yǔ)法規(guī)定,而是一套用來(lái)提高代碼可復(fù)用性、可維護(hù)性、可讀性、穩(wěn)健性以及安全性的解決方案。

1995年,GoF(Gang of Four,四人組/四人幫)合作出版了《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書(shū),共收錄了 23 種設(shè)計(jì)模式,從此樹(shù)立了軟件設(shè)計(jì)模式領(lǐng)域的里程碑,人稱『GoF設(shè)計(jì)模式』。
為什么要學(xué)設(shè)計(jì)模式?
當(dāng)我們回頭看半年前或者一年前自己寫(xiě)的代碼時(shí),我們會(huì)發(fā)現(xiàn):這誰(shuí)寫(xiě)的代碼?寫(xiě)得這么爛?啪啪打臉。
我覺(jué)得主要原因有兩個(gè):
其一,剛接觸代碼不久,對(duì)于剛剛學(xué)習(xí)編程的小伙伴來(lái)說(shuō),編碼還不熟練,要寫(xiě)出雷軍那樣“像詩(shī)一樣優(yōu)雅”的代碼,顯然不太現(xiàn)實(shí),哈哈。
其二,是因?yàn)槲覀儧](méi)有學(xué)習(xí)設(shè)計(jì)模式,設(shè)計(jì)模式是軟件設(shè)計(jì)中常見(jiàn)問(wèn)題的典型解決方案,如果不懂的話,那編碼過(guò)程中就比較難受了。
設(shè)計(jì)模式是前人軟件設(shè)計(jì)智慧的結(jié)晶,學(xué)習(xí)設(shè)計(jì)模式重在理解它的思想,設(shè)計(jì)模式的本質(zhì)是面向?qū)ο笤O(shè)計(jì)原則的實(shí)際運(yùn)用,是對(duì)類的封裝性、繼承性和多態(tài)性以及類的關(guān)聯(lián)關(guān)系和組合關(guān)系充分理解。
學(xué)習(xí)設(shè)計(jì)模式有這幾個(gè)優(yōu)點(diǎn):
可以提高程序員的思維能力、編程能力和設(shè)計(jì)能力。
使程序設(shè)計(jì)更加標(biāo)準(zhǔn)化、代碼編制更加工程化,使軟件開(kāi)發(fā)效率大大提高,從而縮短軟件開(kāi)發(fā)周期。
讓代碼可復(fù)用性高、可讀性強(qiáng)、可靠性高、靈活性好、可維護(hù)性強(qiáng)。
一直以來(lái),我們都在使用別人設(shè)計(jì)好的框架、工具類、庫(kù)等,利用它們的 API 編寫(xiě)我們的程序,但是普通的工具類是沒(méi)有辦法把我們的程序組織成一個(gè)代碼復(fù)用性高、可讀性強(qiáng)、靈活性好、具有彈性的結(jié)構(gòu)。也正因?yàn)槿绱?,才出現(xiàn)了越來(lái)越多的集成式框架,比如說(shuō) Spring、Mybatis 等。這些框架很好地幫我們處理好了這些問(wèn)題,因?yàn)樗鼈儽旧矶际褂昧嗽O(shè)計(jì)模式。所以在開(kāi)發(fā)中,設(shè)計(jì)模式是很重要的,非常有必要把它學(xué)懂。
雷軍說(shuō)過(guò):我沒(méi)有寫(xiě)過(guò)詩(shī),但是有人說(shuō)我寫(xiě)過(guò)的代碼,像詩(shī)一樣優(yōu)雅。
說(shuō)白了,設(shè)計(jì)模式越熟練,寫(xiě)出來(lái)的代碼就更優(yōu)雅,閱讀起來(lái)就很舒服,可維護(hù)性、可擴(kuò)展性就更強(qiáng)。
設(shè)計(jì)模式分類
不同設(shè)計(jì)模式的復(fù)雜程度和應(yīng)用范圍等各方面都不相同,所以可以根據(jù)模式的目的來(lái)進(jìn)行分類。主要分為以下三種:
創(chuàng)建型模式:提供創(chuàng)建對(duì)象的機(jī)制,用于描述“怎么創(chuàng)建對(duì)象”,主要特點(diǎn)是“將對(duì)象的創(chuàng)建與使用分離”。
提供了「單例、原型、工廠方法、抽象工廠、建造者」等 5 種創(chuàng)建型模式。
結(jié)構(gòu)型模式:介紹如何將對(duì)象和類組裝成較大的結(jié)構(gòu)。
提供了「代理、適配器、橋接、裝飾、外觀、享元、組合」等 7 種結(jié)構(gòu)型模式。
行為型模式:負(fù)責(zé)對(duì)象間的高效溝通和職責(zé)委派,也就是用于描述類或?qū)ο笾g怎樣相互協(xié)作完成單個(gè)對(duì)象都無(wú)法單獨(dú)完成的任務(wù),以及怎樣分配職責(zé)。
提供了「模板方法、策略、命令、職責(zé)鏈、狀態(tài)、觀察者、中介者、迭代器、訪問(wèn)者、備忘錄、解釋器」等 11 種行為型模式。
OOP七大原則
上文提到了面向?qū)ο笤O(shè)計(jì)原則,也說(shuō)了設(shè)計(jì)模式是對(duì)設(shè)計(jì)原則的應(yīng)用,到底有哪些原則呢,一起來(lái)看看。名詞記不住不要緊,盡量用通俗易懂的解釋來(lái)幫助理解。
開(kāi)閉原則:對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉
當(dāng)我們的應(yīng)用程序有新需求時(shí),我們盡量不去修改原來(lái)的代碼,而是基于這個(gè)代碼來(lái)進(jìn)行擴(kuò)展。這就是所謂的對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。
里氏替換原則:繼承必須確保超類所擁有的性質(zhì)在子類中依然成立
拿 Java 中的繼承來(lái)舉例,我們盡量不要在子類中更改從父類繼承的方法,而是盡量添加新的方法完成新的功能,如果重寫(xiě)父類方法的話,可復(fù)用性就會(huì)變差,在后期各種模式的詳細(xì)講解中也會(huì)舉例說(shuō)明原因。
依賴倒置原則:要面向接口編程,不要面向?qū)崿F(xiàn)編程
模塊之間不能相互依賴,而是依賴它們的抽象,模塊的細(xì)節(jié)應(yīng)該基于接口來(lái)實(shí)現(xiàn),使用抽象類可以用來(lái)指定約束和規(guī)范。
單一職責(zé)原則:控制類的粒度大小、將對(duì)象解耦、提高其內(nèi)聚性
可以簡(jiǎn)單理解為類中的方法只做一件事情,避免多個(gè)功能堆在一起,降低耦合。
接口隔離原則:要為各個(gè)類建立它們需要的專用接口
其實(shí)就是把接口拆分成更小的接口,和單一職責(zé)原則一樣都是為了將對(duì)象解耦,提高內(nèi)聚性。
迪米特原則:只與你的直接朋友交談,不跟“陌生人”說(shuō)話
一個(gè)對(duì)象其他對(duì)象知道的越少越好,只和朋友通信,不和陌生人說(shuō)話。
合成復(fù)用原則:盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來(lái)實(shí)現(xiàn),其次才考慮使用繼承關(guān)系來(lái)實(shí)現(xiàn)
組合是“有一個(gè)”,繼承為“是一個(gè)”,通?!坝幸粋€(gè)”可能比“是一個(gè)”更好。
另注: 本文在開(kāi)源項(xiàng)目:github.com/MujieJava/JavaStudy 中已收錄,包含計(jì)算機(jī)基礎(chǔ)技術(shù)文章、資源干貨等,資源持續(xù)更新中...
我是木節(jié),覺(jué)得這篇文章對(duì)你有幫助的話,可以來(lái)個(gè)點(diǎn)贊 + 在看,下期再見(jiàn)!
