真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

架構(gòu)設計的五大原則-SOLID-創(chuàng)新互聯(lián)

1.背景

最近在讀《架構(gòu)整潔之道》這一本書,這本書的確寫得不錯,最近也沒有更新文章,一方面再忙工作,另一方面也再啃一些書。當然文章還是得更新,《架構(gòu)整潔之道》里面有些有意思的內(nèi)容我會提取出來外加自己的思考。在這本書里面的第三章介紹了設計原則,這部分我覺得對于大家的平時工作都比較有用。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設計制作、成都網(wǎng)站建設與策劃設計,分宜網(wǎng)站建設哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設10多年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:分宜等地區(qū)。分宜做網(wǎng)站價格咨詢:18982081108

2. 設計原則

想必大家在學習面向?qū)ο蟮臅r候,都學習過下面幾大原則:

  • SRP 單一職責:該設計原則是基于康威定律的推論,每個軟件模塊有且只有一個被更改的理由。

  • OCP 開閉原則:對擴展開放,對修改關閉。

  • LSP 里氏替換原則:任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。

  • ISP 接口隔離原則:在設計中需要避免不需要的依賴。

  • DIP 依賴反轉(zhuǎn)原則:高層策略性代碼不應該依賴底層細節(jié)的代碼,而應該是底層細節(jié)代碼依賴高層策略。

這五個原則也被稱為,SOLID原則取的是他們的首字母。這個也是我們做一個好設計的基礎,接下來會依次對其進行解釋。

3.SRP:單一職責

SRP很容易被大家從字面意思無界,并不是每個模塊只做一個事,而是每個模塊的變化原因只有一個。在書中對于SRP最后的解釋是:

任何一個軟件模塊都應該只對某一類行為者(有共同需求的人)負責。

這里的軟件模塊指的就是一個源代碼文件或者一組緊密相關的函數(shù)和數(shù)據(jù)結(jié)構(gòu)。SRP原則應該是大家運用得最多的原則之一。在書中舉了一個例子,有一個Employee類其中有三個函數(shù):

  • calculatePay():計算工資,由財務部門制定,需要向CFO匯報。

  • reportHours():計算工時,人力資源制定,向COO匯報

  • save():由DBA制定,向CTO匯報。

這里三個函數(shù)都放在了Employee類中,其實也就是把三個行為者的行為都耦合在了一起。一般來說計算工資,會獲取正常工時,而計算工時也會獲取工時,這兩個函數(shù)都依賴了一個獲取工時的方法,如果財務部門計算工資時,想修改邏輯,看大家辛苦了1個小時當1.1個小時發(fā)工資,這個時候修改了這個獲取工時的方法,但是HR部門并不需要這個修改,這個時候就會導致reportHours()這個方法出現(xiàn)數(shù)據(jù)錯誤。所以這個時候就需要將不同行為者的代碼就行拆分。

3.1 如何解決

在書中給出了第一個解決方法:

設計出三個類,每個類都只與一個行為者相關。這種問題的壞處是,程序員需要在程序里處理三個類,這里還介紹了使用門面模式的方法,讓我們只需要在我們使用的地方使用一個類即可:

架構(gòu)設計的五大原則-SOLID

這樣的話我們就不需要關心其他三個類,直接調(diào)用門面模式的方法即可。

3.2 實際場景

在實際場景中微服務可以算作是SRP的思想,雖然每一個微服務不止一個類,但是其整個服務也可以看做是一個模塊,而每個一個模塊基本也只于一個行為者相關。在我們的代碼中可以使用3.1中所描述的方法來進行SRP的實現(xiàn)。

SRP的好處:

  • 修改代碼容易,由于不需要考慮修改代碼是否會影響其他業(yè)務所以是很容易的。

  • 更加容易維護,維護一個什么邏輯都有的代碼明顯比維護一個單一職責的代碼難得多。

  • 容易發(fā)現(xiàn)問題,當出現(xiàn)問題的時候,由于職責清晰,可以比較容易的定位。

  • 松耦合,職責分離,耦合程度比較低。

4.OCP:開閉原則

在這本書中講述OCP可能和大家從一些資料上面看的有點不同。一般大家所認為的開閉原則,應該將那些容易變化的部分進行抽象,利用對抽象的多個實現(xiàn)來進行對擴展開放,而不是直接在類中去修改。

這里我用吃飯的例子來列舉:

每個人一天都會吃三餐,早餐,午餐,晚餐,但是隨著時代的進步,又出現(xiàn)了下午茶,宵夜等,現(xiàn)在一天就不止三餐,那么其實我們就需要在這個類中去添加喝下午茶方法,吃宵夜方法,這樣就導致我們沒增加一個餐的種類就需要添加一個方法,在將SRP的時候我們有個例子,在同一個類中修改方法的時候容易修改其他業(yè)務邏輯,在我們這個例子中我們也會出現(xiàn)這個問題。怎么解決呢?那么我們就可以將變化的部分抽象出來: 架構(gòu)設計的五大原則-SOLID ,后續(xù)如果還需要增加吃的方法那么只需要實現(xiàn)這個接口即可。

但是在這本書中,并沒有去強調(diào)將變化的部分抽象出來,其認為修改是不可避免的,所以我們需要把控好修改的影響,所以提出了高層組件的修改不會影響底層組件,組件層次越低越穩(wěn)定。對于J2EE的開發(fā)者來說,三層開發(fā)肯定并不陌生,controller,service,dao:

如果我們修改controller那么service其實是無感知的,不會受影響,如果我們修改service,dao是不會受影響的,但是我們的controller是會受影響。所以越底層的組件那么其實應該越穩(wěn)定。通過這種方式我們可以控制修改范圍的影響。總結(jié)起來就是通過將系統(tǒng)劃分為一系列組件,并且將這些組件間的依賴關系按層次結(jié)構(gòu)進行組織,使得高階組件不會因低階組件被修改而受到影響。

5.LSP:里氏替換

任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。大多數(shù)人認為LSP其實就是指導如何使用繼承關系的一種方法,尤其是我們在開發(fā)的過程中用spring依賴注入的基本都是基類而非具體的實現(xiàn)類,這個的確也是LSP的一種實現(xiàn)手段。LSP也在逐漸演變成一種更廣泛的,指導接口與其實現(xiàn)方式的設計原則。

這里用書中的一個反面例子來舉例,假如我們現(xiàn)在在構(gòu)建一個提供出租車調(diào)度服務的系統(tǒng),我們提供restful進行調(diào)用,有這么一個司機,如果我們想調(diào)度他那么需要訪問以下請求:

purplecab.com/driver/Bob/pickupAddress/24 Maple St./pickupTime/153/destination/ORD

每個公司想要接入我們的系統(tǒng)都得遵循上面的規(guī)矩,但是有一個公司Acme把destination寫成了縮寫dest,但是由于這個公司比較大,不想修改回來,所以調(diào)度系統(tǒng)只能寫如下的if邏輯:

if(driver.getDispatchUri().startsWith("acme.com"))

這種邏輯一般的軟件架構(gòu)師都不會允許這樣一條語句出現(xiàn)在系統(tǒng)中,如果又出現(xiàn)了一個公司違反了那么是否又需要增加一條if邏輯?軟件架構(gòu)師應該創(chuàng)建一個調(diào)度請求創(chuàng)建組件,并讓該組件使用一個配置數(shù)據(jù)庫來保存URI組裝格式,如下:

URI 調(diào)度格式
Acme.com /pickupAddress/%s/pickupTime/%s/dest/%s
. * . /pickupAddress/%s/pickupTime/%s/destination/%s

但是這樣我們也需要增加一個組件來應對這個情況,也增加了復雜性。

6.ISP:接口隔離原則

首先大家看看下面這個例子:

我們這里的User1,User2,User3都是依賴OPS的,但是User1只需要用op1,User2用op2,User3用op3。在這種情況下,雖然User1不會和op2,op3產(chǎn)生直接的調(diào)用關系,但在源代碼層次上也與他們形成依賴關系。這種依賴關系會導致兩個問題:
  • 修改op2,op3的邏輯會導致op1的邏輯變化

  • 就算邏輯不變化,修改op2也會導致重新編譯和部署User1。

我們通過下面這種方將不同的操作隔離成接口,運用第5節(jié)的LSP,我們將OPS類實現(xiàn)這三個接口,然后替換在User1中的U1Ops,由于依賴的是最小接口所以就不會出現(xiàn)上面的問題。

架構(gòu)設計的五大原則-SOLID

在書中對于ISP強調(diào)得比較多,在后面也講了CRP原則,不要強迫一個組件的用戶依賴他們不需要的東西,CRP是ISP的一個普適版。ISP是針對類來說,CRP是針對組件來說。所以我們總結(jié)起來就是:

不要依賴不需要的東西

7.DIP: 依賴反轉(zhuǎn)

依賴反轉(zhuǎn)其實總結(jié)起來就是多依賴抽象,少依賴具體實現(xiàn)。但是事事并沒有那么絕對,我們的String類是一個具體的實現(xiàn)類但是在我們的代碼中隨處可見,那是不是我們就違反了DIP了呢?其實不是的,我們String已經(jīng)非常穩(wěn)定了,就算修改也會被嚴格的控制,所以我們不需要擔心修改String類會發(fā)生一些意想不到的問題。所以對于我們穩(wěn)定的東西,其實DIP原則就不適用了,而我們需要重點關注的應該經(jīng)常變動的。這里我想要說的一點的是,大家在編碼過程中寫List的時候雖然大多數(shù)時候用的是ArrayList,但是其實很少寫下面這句話ArrayList list = new ArrayList(),更多的是寫List list = new ArrayList(),其實這個就是DIP的一個實現(xiàn)。

這里要說一下為什么叫反轉(zhuǎn)?有反轉(zhuǎn)就有正轉(zhuǎn),如下圖所示:

這里的我們的serviceImpl是service的具體實現(xiàn),在圖中我們的依賴流向沒有發(fā)生變化,所以叫正轉(zhuǎn)。我們采用DIP來進行設計:

可以看見我們這里的最后的流向放生了變化,所以可以叫他依賴反轉(zhuǎn)。

DIP還有幾個編碼規(guī)則需要注意:

  • 多使用抽象接口,盡量避免使用具體實現(xiàn)類。

  • 盡量不要在具體實現(xiàn)類上面創(chuàng)建子類。

  • 盡量不要覆蓋繼承的抽象類的方法:由于我們依賴的是抽象,有可能邏輯中已經(jīng)對這些方法產(chǎn)生了依賴,如果覆蓋有可能會造成問題。

8.總結(jié)

本文講了一下設計的五大原則SOLID,SOLID在這《架構(gòu)整潔之道》中一直貫穿,這五大原則能幫助我們在設計的時候做出更多優(yōu)秀的架構(gòu)設計,如果想了解更多的一些細節(jié)可以看看這本書。

如果你覺得這篇文章對你有文章,可以關注我的技術(shù)公眾號,也可以加入我的技術(shù)交流群進行更多的技術(shù)交流。你的關注和轉(zhuǎn)發(fā)是對我大的支持,O(∩_∩)O。

架構(gòu)設計的五大原則-SOLID


當前文章:架構(gòu)設計的五大原則-SOLID-創(chuàng)新互聯(lián)
標題鏈接:http://weahome.cn/article/jjioi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部