<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          "設(shè)計模式我學(xué)過呀,就是沒用過"

          共 5035字,需瀏覽 11分鐘

           ·

          2021-04-28 19:25


          寫在前面

          在開發(fā)中,不使用設(shè)計模式也不是不可以,但是用好設(shè)計模式能幫忙我們更好的去解決實際問題。

          其實,我們天天都在和設(shè)計模式打交道,很多人卻完全不知道自己在使用設(shè)計模式,你有這種感覺嗎?

          一個不好笑的笑話:

          世界上有10種人,一種是懂設(shè)計模式的,一種是不懂設(shè)計模式的。

          不會有人來問我,還有8種在哪里?大家覺得我該怎么回答。


          什么是設(shè)計模式

          設(shè)計模式( Design Pattern )代表了最佳的實踐,通常被有經(jīng)驗的面向?qū)ο蟮能浖_發(fā)人員所采用。設(shè)計模式是軟件開發(fā)人員在軟件開發(fā)過程中面臨的一般問題的解決方案。這些解決方案是眾多軟件開發(fā)人員經(jīng)過相當長一段時間的試驗和錯誤總結(jié)出來的。

          前人種樹,后人乘涼

          我們可以從以下三個關(guān)鍵點來理解設(shè)計模式:

          • 最佳實踐
          • 解決方案
          • 試驗和錯誤總結(jié)

          從上面的三個關(guān)鍵點中可以總結(jié)出,設(shè)計模式就是在針對編碼過程中遇到的問題總結(jié)出來的最佳解決方案。

          那么這些問題指的是什么問題呢?

          面向?qū)ο蟮某绦驊?yīng)該具有可維護性、代碼可復(fù)用性、擴展性及靈活性,要解決的問題就是代碼可維護性問題、復(fù)用性問題、擴展性問題及靈活性問題。

          簡單來說,設(shè)計模式就是指導(dǎo)你如何寫出可維護、可復(fù)用、可擴展及靈活的代碼。

          在1995年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名為 Design Patterns - Elements of Reusable Object-Oriented Software(中文譯名:設(shè)計模式 - 可復(fù)用的面向?qū)ο筌浖兀?的書,四位作者合稱 GOF(四人組,全拼 Gang of Four),該書收錄了23種設(shè)計模式,是軟件設(shè)計模式領(lǐng)域的里程碑。所有有時候設(shè)計模式我們稱之為GoF23。

          設(shè)計模式的原則

          開閉原則

          開閉原則(Open-Closed Principle,簡稱OCP)是指一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,對修改關(guān)閉。所謂的開閉,也正是對擴展和修改兩個行為的一個原則。

          強調(diào)的是用抽象構(gòu)建框架,用實現(xiàn)擴展細節(jié)??梢蕴岣哕浖到y(tǒng)的可復(fù)用性及可維護性。開閉原則,是面向?qū)ο笤O(shè)計中最基礎(chǔ)的設(shè)計原則。它指導(dǎo)我們?nèi)绾谓⒎€(wěn)定靈活的系統(tǒng),例如:我們版本更新,我盡可能不修改源代碼,但是可以增加新功能。

          依賴倒置原則

          依賴倒置原則(Dependence Inversion Principle簡稱DIP)是指設(shè)計代碼結(jié)構(gòu)時,高層模塊不應(yīng)該依賴底層模塊,二者都應(yīng)該依賴其抽象。抽象不應(yīng)該依賴細節(jié);細節(jié)應(yīng)該依賴抽象。

          通過依賴倒置,可以減少類與類之間的耦合性,提高系統(tǒng)的穩(wěn)定性,提高代碼的可讀性和可維護性,并能夠降低修改程序所造成的風(fēng)險。

          單一職責(zé)原則

          單一職責(zé)(Simple Responsibility Pinciple,簡稱SRP)是指不要存在多于一個導(dǎo)致類變更的原因。假設(shè)我們有一個 Class 負責(zé)兩個職責(zé),一旦發(fā)生需求變更,修改其中一個職責(zé)的

          邏輯代碼,有可能會導(dǎo)致另一個職責(zé)的功能發(fā)生故障。這樣一來,這個 Class 存在兩個導(dǎo)致類變更的原因。如何解決這個問題呢?我們就要給兩個職責(zé)分別用兩個 Class 來實現(xiàn),進行解耦。

          后期需求變更維護互不影響。這樣的設(shè)計,可以降低類的復(fù)雜度,提高類的可 讀 性 , 提 高 系 統(tǒng) 的 可 維 護 性 , 降 低 變 更 引 起 的 風(fēng) 險 。總 體 來 說 就 是 一個Class、Interface、Method 只負責(zé)一項職責(zé)。

          接口隔離原則

          接口隔離原則(Interface Segregation Principle,簡稱ISP)是指用多個專門的接口,而不使用單一的總接口,客戶端不應(yīng)該依賴它不需要的接口。這個原則指導(dǎo)我們在設(shè)計接口時 應(yīng)當注意以下幾點:

          • 一個類對一類的依賴應(yīng)該建立在最小的接口之上。
          • 建立單一接口,不要建立龐大臃腫的接口。
          • 盡量細化接口,接口中的方法盡量少(不是越少越好,一定要適度)。

          接口隔離原則符合我們常說的高內(nèi)聚低耦合的設(shè)計思想,從而使得類具有很好的可讀性、可擴展性和可維護性。我們在設(shè)計接口的時候,要多花時間去思考,要考慮業(yè)務(wù)模型,

          迪米特法則

          迪米特原則(Law of Demeter,簡稱LoD)是指一個對象應(yīng)該對其他對象保持最少的了解,又叫最少知道原則(Least Knowledge Principle,簡稱LKP),盡量降低類與類之間的耦合。

          迪米特原則主要強調(diào)只和朋友交流,不和陌生人說話。出現(xiàn)在成員變量、方法的輸入、輸出參數(shù)中的類都可以稱之為成員朋友類,而出現(xiàn)在方法體內(nèi)部的類不屬于朋友類。

          里氏替換原則

          里氏替換原則(Liskov Substitution Principle,簡稱LSP),在面向?qū)ο蟮某绦蛟O(shè)計中,里氏替換原則是對子類的特別定義,這里給出兩個定義:

          • 如果對每一個類型為S的對象o1,都有類型為T的對象o2,使得以T定義的所有程序P在所有的對象o1都代換成o2時,程序P的行為沒有發(fā)生變化,那么類型S是類型T的子類型。
          • 程序中的對象應(yīng)該是可以在不改變程序正確性的前提下被它的子類所替換的。

          以上兩種定義,反過來就不成立了,有子類出現(xiàn)的地方,父類未必就能適應(yīng)。

          我們可以對里氏替換原則歸納為:

          • 子類可以實現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法。

          • 子類中可以增加自己特有的方法。

          • 當子類的方法重載父類的方法時,方法的前置條件(即方法的輸入/入?yún)ⅲ┮雀割惙椒ǖ妮斎雲(yún)?shù)更寬松。

          • 當子類的方法實現(xiàn)父類的方法時(重寫/重載或?qū)崿F(xiàn)抽象方法),方法的后置條件(即方法的輸出/返回值)要比父類更嚴格或相等。

          使用里氏替換原則有以下優(yōu)點:

          • 約束繼承泛濫,開閉原則的一種體現(xiàn)。
          • 加強程序的健壯性,同時變更時也可以做到非常好的兼容性,提高程序的維護性、擴展性。降低需求變更時引入的風(fēng)險。

          合成復(fù)用原則

          合成復(fù)用原則(Composite/Aggregate Reuse Principle,簡稱CARP)是指盡量使用對象組合(has-a)/聚合(contanis-a),而不是繼承關(guān)系達到軟件復(fù)用的目的??梢允瓜到y(tǒng)更加靈活,降低類與類之間的耦合度,一個類的變化對其他類造成的影響相對較少。繼承我們叫做白箱復(fù)用,相當于把所有的實現(xiàn)細節(jié)暴露給子類。

          組合/聚合也稱之為黑箱復(fù)用,對類以外的對象是無法獲取到實現(xiàn)細節(jié)的。要根據(jù)具體的業(yè)務(wù)場景來做代碼設(shè)計,其實也都需要遵循 OOP模型。

          tips

          學(xué)習(xí)設(shè)計原則,學(xué)習(xí)設(shè)計模式的基礎(chǔ)。在實際開發(fā)過程中,并不是一定要求所有代碼都遵循設(shè)計原則,我們要考慮人力、時間、成本、質(zhì)量,不是刻意追求完美,要在適當?shù)膱鼍白裱O(shè)計原則,體現(xiàn)的是一種平衡取舍,幫助我們設(shè)計出更加優(yōu)雅的代碼結(jié)構(gòu)。

          另外:如果大家覺得還是沒有理解上面的幾個原則,那我下一篇文章使用代碼來詮釋。

          設(shè)計模式的種類

          設(shè)計模式分為三類:

          • 創(chuàng)建型模式
          • 行為性模式
          • 結(jié)構(gòu)性模式

          三種模式的分類如下:


          經(jīng)典案例

          我們最初剛剛開始接觸JDBC那會,第一個JDBC編程如下:

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.ResultSet;
          import java.sql.Statement;

          public class JdbcDemo {
              public static final String URL = "jdbc:mysql://localhost:3306/tian";
              public static final String USER = "root";
              public static final String PASSWORD = "123456"
              
              public static void query() throws Exception {
                  Class.forName("com.mysql.jdbc.Driver");//1
                  Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);//2
                  Statement stmt = conn.createStatement();//3
                  ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1");//4
                  while(rs.next()){
                      System.out.println("name: "+rs.getString("name")+" 年齡:"+rs.getInt("age"));
                  }
              }
          }

          這個案例中,我們可以把JDBC編程分為五個步驟。

          一個查詢寫了五個步驟,再來個新增又寫五個步驟,再來個刪除又寫五個步驟....長此以往下去,真的成為“搬磚人了”,這是不使用任何設(shè)計模式的代價。

          天天寫這種重復(fù)的代碼,自己很累,工作效率低,長此以往的下去,就算你干了10年還不如很多人一年的工作經(jīng)驗。

          推薦書籍

          1.《大話設(shè)計模式


          2.《Head First設(shè)計模式

          3.《設(shè)計模式之禪

          大家可以從三本書中,選擇自己最喜歡的,其實都講的挺好的,但我們只需選擇最適合適合自己的才是王道。

          總結(jié)

          設(shè)計模式的本質(zhì):設(shè)計模式用于承載復(fù)雜的業(yè)務(wù)邏輯,使寫出的代碼簡潔、易擴展 。

          你可以不用學(xué)設(shè)計模式,照樣寫代碼很溜、照樣能實現(xiàn)功能、照樣能領(lǐng)到那點點薪資。有點志氣的、有點追求的、有點報復(fù)的人,肯定會學(xué)設(shè)計模式。

          tips

          本人從今天開始,開啟架構(gòu)師學(xué)習(xí)之旅,主要內(nèi)容如下:

          • 設(shè)計模式
          • 分布式與高并發(fā)(線程、JUC等)
          • 分布式與微服務(wù)(Spring Boot、Spring Cloud、Dubbo)
          • Spring源碼分析
          • Mybatis源碼分析
          • Dubbo源碼
          • 性能優(yōu)化(JVM、Tomcat、MySQL)
          • 工具(Maven、Git、Docker、K8S等)
          — 【 THE END 】—
          本公眾號全部博文已整理成一個目錄,請在公眾號里回復(fù)「m」獲取!


          3T技術(shù)資源大放送!包括但不限于:Java、C/C++,Linux,Python,大數(shù)據(jù),人工智能等等。在公眾號內(nèi)回復(fù)「1024」,即可免費獲?。?!




          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一区麻豆4| 伊人久久网站 | 九九视频在线观看国产 | 国模逼逼 | 日日嗨夜夜嗨一区二区 |