欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

深入淺出精講面向?qū)ο笤O(shè)計七大原則,徹底領(lǐng)悟設(shè)計背后思想-創(chuàng)新互聯(lián)

深入淺出精講面向?qū)ο笤O(shè)計七大原則,徹底領(lǐng)悟設(shè)計背后思想
  • 歡迎閱讀
    • 一、面向?qū)ο笤O(shè)計原則提出背景
    • 二、面向?qū)ο笤O(shè)計七大原則總覽
    • 三、單一職責(zé)原則(SRP)
      • 3.1定義:
      • 3.2分析:
      • 3.3舉例:
    • 四、開閉原則(OCP)
      • 4.1定義:
      • 4.2分析:
      • 4.3舉例:
    • 五、里氏替換原則(LSP)
      • 5.1定義:
      • 5.2分析:
      • 5.3舉例:
    • 六、依賴倒轉(zhuǎn)原則(DIP)
      • 6.1定義:
      • 6.2分析:
      • 6.3舉例:
    • 七、接口隔離原則(ISP)
      • 7.1定義:
      • 7.2分析:
      • 7.3舉例:
    • 八、迪米特法則(LOD)
      • 8.1定義:
      • 8.2分析:
      • 8.3舉例:
    • 九、合成復(fù)用口原則(CRP)
      • 9.1定義:
      • 9.2分析:
      • 9.3舉例:
    • 十、面向?qū)ο笤O(shè)計原則總結(jié)

創(chuàng)新互聯(lián)建站是一家集成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、網(wǎng)站頁面設(shè)計、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)網(wǎng)站制作公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗,以探求精品塑造與理念升華,設(shè)計最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅持講誠信,負(fù)責(zé)任的原則,為您進行細(xì)心、貼心、認(rèn)真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。歡迎閱讀

對面向?qū)ο笤O(shè)計原則的學(xué)習(xí)能夠提高大家的系統(tǒng)設(shè)計能力和代碼編寫質(zhì)量。本文內(nèi)容豐富易懂,對每一個面向?qū)ο笤O(shè)計原則都會舉出具體的例子來進行講解。在文章最后會對所有的面向?qū)ο笤O(shè)計原則進行總結(jié)。另外,本篇文章有配套的講解視頻(如果不想看文字就去看視頻叭),請點擊這里觀看(嗶哩嗶哩-小勾狗有什么壞心眼呢-bili_88094125658)。歡迎大家閱讀和觀看~希望通過這篇文章的分享能夠使得大家在今后利用面向?qū)ο笳Z言編寫代碼時給大家?guī)硪恍椭?/p>一、面向?qū)ο笤O(shè)計原則提出背景

對于我們后端來說,平時大部分時間都在使用面向?qū)ο笳Z言來設(shè)計軟件系統(tǒng)。對于面向?qū)ο筌浖到y(tǒng)的設(shè)計而言,在支持可維護性的同時,提高系統(tǒng)的可復(fù)用性是一個至關(guān)重要的問題,如何同時提高一個軟件系統(tǒng)的可維護性和可復(fù)用性是面向?qū)ο笤O(shè)計需要解決的核心問題之一。像我們平時接觸的23種設(shè)計模式就是以面向?qū)ο笃叽笤瓌t為基礎(chǔ)進行設(shè)計的。所以對面向?qū)ο笤O(shè)計的七大原則的學(xué)習(xí)有助于提高我們的設(shè)計水平,使我們設(shè)計的軟件系統(tǒng)有較高的可維護性和可復(fù)用性。今天呢,我會通過具體案例,深入淺出精講面向?qū)ο笤O(shè)計七大原則,讓大家徹底領(lǐng)悟設(shè)計背后的思想。

二、面向?qū)ο笤O(shè)計七大原則總覽

這張表展示了今天會分享到的七大原則。下面我會結(jié)合具體的例子來一一分享各個原則。

設(shè)計原則名稱設(shè)計原則簡介
單一職責(zé)原則(Single Responsibility Principle, SRP)類的職責(zé)要單一,不能將太多的職責(zé)放在一個類中
開閉原則(Open-Closed Principle, OCP)軟件實體對擴展是開放的,但對修改是關(guān)閉的,即在不修改一個軟件實體的基礎(chǔ)上去擴展其功能
里氏代換原則(Liskov Substitution Principle, LSP)在軟件系統(tǒng)中,一個可以接受基類對象的地方必然可以接受一個子類對象
依賴倒轉(zhuǎn)原則(Dependency Inversion Principle, DIP)要針對抽象層編程,而不要針對具體類編程
接口隔離原則(Interface Segregation Principle, ISP)使用多個專門的接口來取代一個統(tǒng)一的接口
合成復(fù)用原則(Composite Reuse Principle, CRP)在系統(tǒng)中應(yīng)該盡量多使用組合和聚合關(guān)聯(lián)關(guān)系,盡量少使用甚至不使用繼承關(guān)系
迪米特法則(Law of Demeter, LoD)一個軟件實體對其他實體的引用越少越好,或者說如果兩個類不必彼此直接通信,那么這兩個類就不應(yīng)當(dāng)發(fā)生直接的相互作用,而是通過引入一個第三者發(fā)生間接交互
三、單一職責(zé)原則(SRP) 3.1定義:

首先來看第一個原則,單一職責(zé)原則。單一職責(zé)原則有兩種定義方式。
第一種定義是一個對象應(yīng)該只包含單一的職責(zé),并且該職責(zé)被完整地封裝在一個類中。(Every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.)
第二種定義是就一個類而言,應(yīng)該僅有一個引起它變化的原因。(There should never be more than one reason for a class to change.)

3.2分析:

下面我們做一個具體分析。類的職責(zé)主要包括兩個方面:數(shù)據(jù)職責(zé)和行為職責(zé),數(shù)據(jù)職責(zé)通過其屬性來體現(xiàn),而行為職責(zé)通過其方法來體現(xiàn)。顯而易見,一個類(或者大到模塊,小到方法)承擔(dān)的職責(zé)越多,它被復(fù)用的可能性越小,而且如果一個類承擔(dān)的職責(zé)過多,就相當(dāng)于將這些職責(zé)耦合在一起,當(dāng)其中一個職責(zé)變化時,可能會影響其他職責(zé)的運作。

3.3舉例:

下面通過舉例Java的C/S系統(tǒng)的“登錄功能”來說明單一職責(zé)原則。在圖中,登錄類中的init方法是初始化方法、display是顯示方法、validate是數(shù)據(jù)驗證方法、getConnection是鏈接數(shù)據(jù)庫的方法、findUser是通過數(shù)據(jù)庫校驗用戶名和密碼的方法、main方法是整個系統(tǒng)運行的方法?,F(xiàn)在我們來看看他是不是符合單一職責(zé)原則。單一職責(zé)原則是一個類應(yīng)該只包含一個單一的職責(zé),而現(xiàn)在我們看到,Login類中其實包含了三種職責(zé)。首先是init方法、display方法和validate方法組成的展示頁面的職責(zé)、然后是getConnection方法和findUser方法組成的查詢數(shù)據(jù)庫的職責(zé)、最后是main方法構(gòu)成的運行整個系統(tǒng)的職責(zé)。我們說就一個類而言,應(yīng)該僅有一個引起它變化的原因。如果說我們現(xiàn)在需要對顯示做變換,那么我們需要修改display方法從而導(dǎo)致Login類被修改、而如果我們說現(xiàn)在需要修改數(shù)據(jù)庫的鏈接方式,那么我們需要修改getConnection方法同樣會導(dǎo)致Login類被修改,再如果說我們要修改main方法比如在運行前需要添加一下處理,那么就需要修改Login類種main方法。所以說Login類現(xiàn)在能引起它變化的原因有很多種。這顯然不太好。

在這里插入圖片描述
現(xiàn)在我們使用單一職責(zé)原則對其進行重構(gòu)。對于這四個類的介紹,可以點擊這里觀看視頻(在5分00秒處)?,F(xiàn)在我們看到我們把Login類劃分成了四個不同的類,每個類有自己的單一職責(zé),也就是說每一個類現(xiàn)在引起他們變換的原因都只有一個。也就是說現(xiàn)在四個類是四個正交的維度,他們之間的變換是無關(guān)的。像現(xiàn)在這樣的設(shè)計就符合了單一職責(zé)原則。這樣當(dāng)因為變化需要修改時,就可以只修改對應(yīng)的模塊而不用影響其它的模塊??梢钥吹浆F(xiàn)在的設(shè)計,在可維護性和可復(fù)用性上都比之前的設(shè)計好很多了。比如說我們想更改getConnection方法,那么我們只會去修改UserDAO類,而其它類不會受到影響。而且引起UserDAO發(fā)生改變的原因只有一個,而不是很多個。
在這里插入圖片描述

四、開閉原則(OCP) 4.1定義:

第二個原則,開閉原則。開閉原則定義是一個軟件實體應(yīng)當(dāng)對擴展開放,對修改關(guān)閉。(Software entities should be open for extension, but closed for modification.)也就是說在設(shè)計一個模塊的時候,應(yīng)當(dāng)使這個模塊可以在不被修改的前提下被擴展,即實現(xiàn)在不修改源代碼的情況下改變這個模塊的行為。

4.2分析:

開閉原則由Bertrand Meyer于1988年提出,也就是下面圖片中的這個人,旁邊這兩本經(jīng)典的書就是他寫的。開閉原則是面向?qū)ο笤O(shè)計中最重要的原則之一。在開閉原則的定義中,軟件實體可以指一個軟件模塊、一個由多個類組成的局部結(jié)構(gòu)或一個獨立的類。在開閉原則中,抽象化是它的關(guān)鍵。開閉原則還可以通過一個更加具體的“對可變性封裝原則”(Principle of Encapsulation of Variation, EVP)來描述,其中“對可變性封裝原則”要求找到系統(tǒng)的可變因素并將其封裝起來。
在這里插入圖片描述

4.3舉例:

現(xiàn)在通過舉例圖像界面系統(tǒng)中各種不同的按鈕來說明開閉原則的應(yīng)用。某圖形界面系統(tǒng)提供了各種不同形狀的按鈕,客戶端代碼可針對這些按鈕進行編程,用戶可能會改變需求要求使用不同的按鈕,原始設(shè)計方案如圖所示。其中LoginForm是登錄頁面,包含一個button按鈕,display顯示方法會根據(jù)不同類型的button按鈕展示不同樣式的button??梢钥吹?,每當(dāng)需要變換按鈕時,需要修改LoginForm中的代碼,而這違反了開閉原則中所說的對修改關(guān)閉。另外,如果用戶需要新的Button時,需要重新定義一個button然后修改LoginForm的代碼,這對擴展很不方便?,F(xiàn)在我們需要思考如何更改設(shè)計,來達到在不修改代碼的情況下做到擴展。
在這里插入圖片描述
在這里插入圖片描述
現(xiàn)在我們使用開閉原則對其進行重構(gòu)。重新構(gòu)造后的結(jié)構(gòu)如圖所示。對于這張圖的介紹,可以點擊這里觀看視頻(在9分37秒處)?,F(xiàn)在,當(dāng)我們需要變換按鈕時只需要修改配置文件就可以改變按鈕的樣式了,另外,如果有新的按鈕,我們只需要增加一個新button類繼承AbstractButton,然后修改配置文件就可以很方便地進行擴展了,可以看到我們并沒有修改任何LoginForm中的代碼就實現(xiàn)了擴展,現(xiàn)在的設(shè)計比之前的設(shè)計好了很多。
在這里插入圖片描述
這里的配置文件可以讓LoginForm中AbstractButton類型的button對象是配置文件中指定的類(例如圖中是CircleButton)的實例。

五、里氏替換原則(LSP) 5.1定義:

第三個原則,里氏替換原則。里氏替換原則有兩種方式的定義,第一個定義是:如果對每一個類型為S的對象o1,都有類型為T的對象o2,使得以T定義的所有程序P在所有的對象o2都代換成o1時,程序P的行為沒有變化,那么類型S是類型T的子類型。(If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.)

第二定義是:所有引用基類(父類)的地方必須能透明地使用其子類的對象。(Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.)

其中定義一比較重要的一點是替換后行為沒有發(fā)生變化,也就是說如果替換后行為發(fā)生了變化或者代碼運行時出現(xiàn)行為/業(yè)務(wù)錯誤,那么這兩個類就不應(yīng)該是父子關(guān)系。定義二中比較重要的是透明這一個詞,透明的含義是指,當(dāng)基類被子類替換時,感覺不到基類被子類替換了,也就是行為不會發(fā)生變化。

5.2分析:

里氏代換原則由2008年圖靈獎得主、美國第一位計算機科學(xué)女博士、麻省理工學(xué)院教授Barbara Liskov和卡內(nèi)基.梅隆大學(xué)Jeannette Wing教授于1994年提出。也就是下面這兩位。里氏代換原則可以通俗表述為:在軟件中如果能夠使用基類對象,那么一定能夠使用其子類對象。把基類都替換成它的子類,程序?qū)⒉粫a(chǎn)生任何錯誤和異常,反過來則不成立,如果一個軟件實體使用的是一個子類的話,那么它不一定能夠使用基類。里氏代換原則是實現(xiàn)開閉原則的重要方式之一,由于使用基類對象的地方都可以使用子類對象,因此在程序中盡量使用基類類型來對對象進行定義,而在運行時再確定其子類類型,用子類對象來替換父類對象。
在這里插入圖片描述
在這里插入圖片描述

5.3舉例:

現(xiàn)在通過舉例對數(shù)據(jù)進行加密來說明里氏替換原則的應(yīng)用。(這里舉例比較復(fù)雜,建議觀看視頻(在13分57秒處)。)如圖所示,某系統(tǒng)現(xiàn)在需要對重要數(shù)據(jù),如用戶密碼,進行加密處理,在數(shù)據(jù)操作類DataOperator中需要調(diào)用加密類中定義的加密算法encrypt,系統(tǒng)提供了兩個不同的加密類,CipherA和CipherB,它們實現(xiàn)不同的加密方法,在DataOperator中可以選擇其中一個實現(xiàn)加密操作?,F(xiàn)在考慮一個問題,如果需要更換一個加密算法類或者增加并使用一個新的加密算法類,如將CipherA改為CipherB(Client中的main方法需要修改為new CipherB,setCipherB,)或添加一個新的加密算法CipherC(DataOperator中的encrypt方法需要添加ifelse、DataOperator類還要添加一個CipherC、main方法也需要修改),則需要修改客戶類Client和數(shù)據(jù)操作類DataOperator的源代碼,這違背了開閉原則。
在這里插入圖片描述
Client中的main方法:
在這里插入圖片描述

DataOperator中的setCipherA方法:
在這里插入圖片描述

DataOperator中的encrypt方法:
在這里插入圖片描述
現(xiàn)在使用里氏代換原則對其進行重構(gòu),使得系統(tǒng)可以靈活擴展,符合開閉原則。重構(gòu)后的結(jié)構(gòu)如圖所示,當(dāng)需要修改加密算法時,可以直接需改配置文件;如果需要擴展加密算法,可以添加新的加密算法繼承CipherA類,然后修改Config配置文件就行,保證了對修改關(guān)閉對擴展開放??梢钥吹酵ㄟ^里氏代換原則確保了開閉原則。從而提高了系統(tǒng)的可維護性和可復(fù)用性。
在這里插入圖片描述
Client中的main方法:
在這里插入圖片描述

另外,里氏替換原則還可以用來判別兩個類是否應(yīng)該為父子關(guān)系。下面看某公司給員工計算報酬的例子。其中{A}代表是一個抽象類。Employee是員工類,它是領(lǐng)月薪員工和領(lǐng)時薪員工的父類,Timecard是用來記錄時薪員工的小時數(shù)。Employee中的抽象方法calcPay方法用來計算工資,由各個子類負(fù)責(zé)具體實現(xiàn)。
在這里插入圖片描述
現(xiàn)在考慮如果要增加一個VolunteerEmployee志愿者員工類繼承至Employee類,即這類員工沒有薪水,那么calcPay該怎么實現(xiàn)
第一種方法,return 0:

在這里插入圖片描述

第一種方法返回return 0,但是這樣沒有意義,因為如果在其它地方有一個轉(zhuǎn)賬方法,那么它會給志愿者轉(zhuǎn)賬0元,沒有實際意義,志愿者打開手機銀行一看給我轉(zhuǎn)賬0元是什么意思?

第二種方法,拋異常:

在這里插入圖片描述

第二種方法拋異常。如果拋異常的話要么異常必須被捕獲,要么調(diào)用者說明,因此,在一個派生類上的約束已經(jīng)影響到了基類用戶。

另外如果使用第二種方法,那原來的計算所有員工工資的代碼會這樣變動:
原來的代碼:

在這里插入圖片描述

變動后的代碼:
使用try catch語句

在這里插入圖片描述

或者
使用instaceof判斷是哪個類型,但這樣更糟糕,因為原來基于Employee基類的代碼,現(xiàn)在必須要明確引用它的一個子類VolunteerEmployee

在這里插入圖片描述

但不管哪樣變動,都影響到了其它地方。其根源在于違背了里氏替換原則,因為VolunteerEmployee不能和Employee是父子關(guān)系。如果是父子關(guān)系會違背里氏替換原則,VolunteerEmployee不能透明地替代Employee。只要當(dāng)調(diào)用一個派生類上的方法時造成了非法使用,就會違反里氏替換原則;如果使用了一個退化的派生類的方法(什么也沒實現(xiàn)),也是違反里氏替換原則。此時說明該方法對派生類是無意義的。繼承應(yīng)該是關(guān)于行為的,而不是志愿者員工從直覺上判斷就是員工類,而是從行為上來判斷是否屬于員工類。很明顯這里的員工類是計算薪水的員工,而志愿者員工不計算薪水,所以志愿者員工不應(yīng)該繼承員工類。通過里氏替換原則可以幫助我們來判斷兩個類是否應(yīng)該用繼承關(guān)系。

六、依賴倒轉(zhuǎn)原則(DIP) 6.1定義:

第四個原則,依賴倒轉(zhuǎn)原則。依賴倒轉(zhuǎn)原則有兩種方式的定義。

第一種定義是:高層模塊不應(yīng)該依賴低層模塊,它們都應(yīng)該依賴抽象。抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。(High level modules should not depend upon low level modules, both should depend upon abstractions. Abstractions should not depend upon details, details should depend upon abstractions.)

第二種定義是:要針對接口編程,不要針對實現(xiàn)編程。(Program to an interface, not an implementation.)

6.2分析:

依賴倒轉(zhuǎn)原則是Robert C. Martin在1996年為《C++ Reporter》所寫的專欄Engineering Notebook的第三篇,后來加入到他在2002年出版的經(jīng)典著作《Agile Software Development, Principles, Patterns, and Practices》中。也就是下面這個人和他寫的經(jīng)典書籍。簡單來說,依賴倒轉(zhuǎn)原則就是指:代碼要依賴于抽象的類,而不要依賴于具體的類;要針對接口或抽象類編程,而不是針對具體類編程。依賴倒轉(zhuǎn)原則要求客戶端依賴于抽象耦合,以抽象方式耦合是依賴倒轉(zhuǎn)原則的關(guān)鍵。

在這里插入圖片描述

6.3舉例:

現(xiàn)在通過舉例來說明依賴倒置原則的應(yīng)用。如圖中所示,現(xiàn)在代碼一共有三層,高層模塊Policy layer是策略層,中層模塊Mechanism Layer是機制層,它對策略層進一步實現(xiàn),底層模塊Utility Layer是工具層,提供一些工具層的東西給中層模塊使用。可以看到,高層調(diào)用了中層然后中層又調(diào)用了底層,越往下相對于上一層實現(xiàn)的越具體(上一層相當(dāng)于抽象,下一層相當(dāng)于具體,抽象依賴于具體)。這樣的設(shè)計看起來似乎是正確的,但實際上是不好的。因為高層模塊Policy layer對下面的兩個層的改動都很敏感,中層模塊對底層模塊的改動很敏感。如果底層模塊有改動,那么中層模塊可能也會隨之改動從而可能導(dǎo)致高層也會改動。
在這里插入圖片描述

現(xiàn)在我們使用依賴倒置原則對其進行重構(gòu)。重新構(gòu)造后的結(jié)構(gòu)如圖所示。我們在每一層添加抽象化的接口,使下一層實現(xiàn)這個接口。這樣當(dāng)下一層發(fā)生改變時,因為上一層和下一層中間的接口沒有發(fā)生改變所以不會影響到上一層,上一層只依賴于抽象的接口而不是下一層具體的實現(xiàn)。這樣就降低了模塊間的耦合,提高了系統(tǒng)的可維護性和可復(fù)用性。
在這里插入圖片描述

七、接口隔離原則(ISP) 7.1定義:

第五個原則,接口隔離原則。接口隔離原則有兩種方式的定義。

第一種定義是:客戶端不應(yīng)該依賴那些它不需要的接口。(Clients should not be forced to depend upon interfaces that they do not use.)

第二種定義是:一旦一個接口太大,則需要將它分割成一些更細(xì)小的接口,使用該接口的客戶端僅需知道與之相關(guān)的方法。(Once an interface has gotten too ‘fat’ it needs to be split into smaller and more specific interfaces so that any clients of the interface will only know about the methods that pertain to them.)

7.2分析:

接口隔離原則是指使用多個專門的接口,而不使用單一的總接口。每一個接口應(yīng)該承擔(dān)一種相對獨立的角色,不多不少,不干不該干的事,該干的事都要干。使用接口隔離原則拆分接口時,首先必須滿足單一職責(zé)原則,將一組相關(guān)的操作定義在一個接口中,且在滿足高內(nèi)聚的前提下,接口中的方法越少越好??梢栽谶M行系統(tǒng)設(shè)計時采用定制服務(wù)的方式,即為不同的客戶端提供寬窄不同的接口,只提供用戶需要的行為,而隱藏用戶不需要的行為。

7.3舉例:

現(xiàn)在通過客戶系統(tǒng)來說明接口隔離原則的應(yīng)用。如圖展示了一個擁有多個客戶類的系統(tǒng),在系統(tǒng)中定義了一個巨大的接口(胖接口)AbstractService來服務(wù)所有的客戶類??梢钥吹綄τ贑lienA類,AbstractService在提供operatorA方法的同時還提供了它不需要的operatorB和operatorC方法,對于ClienB類和ClienC類均是如此。顯而易見,這并不合理。因為一是接口的實現(xiàn)類龐大,實現(xiàn)類中需要實現(xiàn)接口中的所有方法,靈活性較差,如果某些方法不實現(xiàn)而是大量空方法,將導(dǎo)致系統(tǒng)中產(chǎn)生很多無用的代碼,影響代碼的質(zhì)量。另外由于客戶端針對大接口編程,將在一定程度上破壞程序的封裝性,客戶端看到了不應(yīng)該看到的方法,沒有為客戶端定制接口。這樣的設(shè)計結(jié)構(gòu)違背了接口隔離原則。
在這里插入圖片描述

現(xiàn)在我們使用接口隔離原則對其進行重構(gòu)??梢钥吹轿覀儗bstractService進行了分割,分割成了多個細(xì)小的接口。對于每一個客戶類,只需要依賴它需要的接口就行了。如此以來不同的客戶類使用不同的接口,只提供客戶類需要的行為,隱藏了客戶類不需要的行為。這樣的設(shè)計顯然是合理的。
在這里插入圖片描述

八、迪米特法則(LOD) 8.1定義:

接下來要介紹的是迪米特法則(Law of Demeter, LoD)又稱為最少知識原則(Least Knowledge Principle, LKP),它有多種定義方法,其中幾種典型定義如下。
第一種定義是不要和“陌生人”說話(Don’t talk to strangers.)。
第二種定義是只與你的直接朋友通信(Talk only to your immediate friends.)。
第三種定義是每一個軟件單位對其他的單位都只有最少的知識,而且局限于那些與本單位密切相關(guān)的軟件單位(Each unit should have only limited knowledge about other units: only units “closely” related to the current unit.)。

8.2分析:

簡單來說,迪米特法則就是指一個軟件實體應(yīng)當(dāng)盡可能少的與其他實體發(fā)生相互作用。這樣,當(dāng)一個模塊修改時,就會盡量少的影響其他的模塊,擴展會相對容易,這是對軟件實體之間通信的限制,它要求限制軟件實體之間通信的寬度和深度。

在迪米特法則中,對于一個對象,其朋友包括以下幾類:
(1) 當(dāng)前對象本身(this);
(2) 以參數(shù)形式傳入到當(dāng)前對象方法中的對象;
(3) 當(dāng)前對象的成員對象;
(4) 如果當(dāng)前對象的成員對象是一個集合,那么集合中的元素也都是朋友;
(5) 當(dāng)前對象所創(chuàng)建的對象。任何一個對象,如果滿足上面的條件之一,就是當(dāng)前對象的“朋友”,否則就是“陌生人”。

在狹義的迪米特法則中,如果兩個類之間不必彼此直接通信,那么這兩個類就不應(yīng)當(dāng)發(fā)生直接的相互作用,如果其中的一個類需要調(diào)用另一個類的某一個方法的話,可以通過第三者轉(zhuǎn)發(fā)這個調(diào)用。下面這張圖的介紹請觀看視頻(在33分48秒處)
在這里插入圖片描述

迪米特法則的主要用途在于控制信息的過載:
1.在類的劃分上,應(yīng)當(dāng)盡量創(chuàng)建松耦合的類,類之間的耦合度越低,就越有利于復(fù)用,一個處在松耦合中的類一旦被修改,不會對關(guān)聯(lián)的類造成太大波及;
2.在類的結(jié)構(gòu)設(shè)計上,每一個類都應(yīng)當(dāng)盡量降低其成員變量和成員函數(shù)的訪問權(quán)限;
3.在類的設(shè)計上,只要有可能,一個類型應(yīng)當(dāng)設(shè)計成不變類;
4.在對其他類的引用上,一個對象對其他對象的引用應(yīng)當(dāng)降到最低。

8.3舉例:

現(xiàn)在通過舉例來說明迪米特法則的應(yīng)用。如圖展示了某系統(tǒng)界面類(如Form1、Form2等類)與數(shù)據(jù)訪問類(如DAO1、DAO2等類)之間的調(diào)用,可以從圖中看到它們的調(diào)用關(guān)系較為復(fù)雜。迪米特法則強調(diào)不要有太多的緊耦合而是應(yīng)該是采用松耦合,一個軟件實體應(yīng)當(dāng)盡可能少的與其他實體發(fā)生相互作用??梢钥吹?,F(xiàn)orm3與DAO2-4這三個DAO都有關(guān)聯(lián),其中有一個發(fā)生變換都會影響到Form3。另外DAO2發(fā)生改變除了會影響Form3還會影響Form4,Form5,所以下面的設(shè)計是一個不太好的設(shè)計。
在這里插入圖片描述
現(xiàn)在我們使用迪米特法則對其進行重構(gòu)。重構(gòu)的結(jié)果如圖所示??梢钥吹?,我們在Form和DAO的中間添加了一個中間層Controller,這樣就降低了系統(tǒng)的耦合。Form通過中間的Controller與DAO發(fā)生間接的通信。這樣當(dāng)DAO發(fā)生改變時就不會影響到Form,達到了Form盡可能少的與其他實體發(fā)生相互作用的目的。
在這里插入圖片描述

九、合成復(fù)用口原則(CRP) 9.1定義:

最后一個原則,合成復(fù)用原則。合成復(fù)用的定義是盡量使用對象組合,而不是繼承來達到復(fù)用的目的。(Favor composition of objects over inheritance as a reuse mechanism.)

9.2分析:

合成復(fù)用原則就是指在一個新的對象里通過關(guān)聯(lián)關(guān)系(包括組合關(guān)系和聚合關(guān)系)來使用一些已有的對象,使之成為新對象的一部分;新對象通過委派調(diào)用已有對象的方法達到復(fù)用其已有功能的目的。簡言之:要盡量使用組合/聚合關(guān)系,少用繼承。因為通過繼承來復(fù)用,雖然實現(xiàn)簡單。但破壞系統(tǒng)的封裝性;從基類繼承而來的實現(xiàn)是靜態(tài)的,不可能在運行時發(fā)生改變,沒有足夠的靈活性;只能在有限的環(huán)境中使用。(“白箱”復(fù)用 )而通過組合/聚合來復(fù)用,可以使耦合度相對較低,選擇性地調(diào)用成員對象的操作;可以在運行時動態(tài)進行。(“黑箱”復(fù)用 )

9.3舉例:

現(xiàn)在舉例來說明接口隔離原則的應(yīng)用。某教學(xué)管理系統(tǒng)部分?jǐn)?shù)據(jù)庫訪問類設(shè)計如圖所示,可以看到StudentDAO和TeachearDAO通過繼承來復(fù)用DBUtil中的getConnection方法來鏈接數(shù)據(jù)庫,首先可以發(fā)現(xiàn)DBUtil和Student/TeachearDAO不是is-a的關(guān)系,也就是從語義來說不應(yīng)該繼承關(guān)系。另外,如果需要更換數(shù)據(jù)庫連接方式,如原來采用JDBC連接數(shù)據(jù)庫,現(xiàn)在采用數(shù)據(jù)庫連接池連接,則需要修改DBUtil類源代碼。如果StudentDAO采用JDBC連接,但是TeacherDAO采用連接池連接,則需要增加一個新的DBUtil類,并修改StudentDAO或TeacherDAO的源代碼,使之繼承新的數(shù)據(jù)庫連接類,這將違背開閉原則,系統(tǒng)擴展性較差。
在這里插入圖片描述
現(xiàn)在我們使用合成復(fù)用原則對其進行重構(gòu)。重構(gòu)的結(jié)果如圖所示??梢钥吹竭@一次我們采用了聚合的方式來復(fù)用DBUtil。這樣一來當(dāng)我們需要換數(shù)據(jù)庫鏈接方法時,可以創(chuàng)建一個新類NewDBUtil來繼承DBUtil從而在滿足開閉原則的前提下,對功能進行擴展??梢钥吹叫碌脑O(shè)計結(jié)構(gòu)提高了系統(tǒng)的可維護性和可復(fù)用性。
在這里插入圖片描述

十、面向?qū)ο笤O(shè)計原則總結(jié)

七大原則本質(zhì)上指導(dǎo)了兩件事情,第一件事情是一個類該如何設(shè)計,第二件事情是兩個類關(guān)系該如何設(shè)計。對于一個類該如何設(shè)計主要遵循單一職責(zé)原則,即類的職責(zé)要單一,不能將太多的職責(zé)放在一個類中,類的變化點要盡可能少和開閉原則,即軟件實體對擴展是開放的,但對修改是關(guān)閉的,即在不修改一個軟件實體的基礎(chǔ)上去擴展其功能。這兩個原則使得一個類滿足高內(nèi)聚。對于2個類關(guān)系該如何設(shè)計,從策略上來講,最鼓勵我們?nèi)プ裱氖紫仁堑厦滋胤▌t,即兩個類盡量不要發(fā)生關(guān)系,要盡量少的去發(fā)生關(guān)系;如果非要發(fā)生關(guān)系,鼓勵遵循依賴倒置原則,要依賴抽象,和抽象發(fā)生關(guān)系而不是具體的類發(fā)生關(guān)系,即要針對抽象層編程,而不要針對具體類編程;接著就是,若發(fā)生依賴關(guān)系,要注意接口隔離原則,即,使用多個專門的接口來取代一個統(tǒng)一的接口,要依賴也僅僅依賴自己需要的服務(wù);如果現(xiàn)在有復(fù)用的需要,應(yīng)該優(yōu)先使用關(guān)聯(lián)關(guān)系而不是繼承,即遵循合成復(fù)用原則;如果關(guān)聯(lián)關(guān)系滿足不了要求,非要用繼承,那么此時就應(yīng)該遵循里氏替換原則,即所有引用基類(父類)的地方必須能透明地使用其子類的對象。迪米特法則、依賴倒置原則、接口最小隔離原則、合成復(fù)用原則和里氏替換原則使得類之間滿足松耦合。
在這里插入圖片描述
在這里插入圖片描述

可見遵循面向?qū)ο笤O(shè)計的七大原則可以使我們的系統(tǒng)實現(xiàn)高內(nèi)聚松耦合并且能夠提高系統(tǒng)的可維護性和可復(fù)用性,希望通過今天的分享能夠使得大家在今后利用面向?qū)ο笳Z言編寫代碼時給大家?guī)硪恍椭?,使得在設(shè)計系統(tǒng)時更合理,編寫代碼時質(zhì)量更高,以上就是今天給大家分享的全部內(nèi)容,感謝大家的閱讀。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

當(dāng)前文章:深入淺出精講面向?qū)ο笤O(shè)計七大原則,徹底領(lǐng)悟設(shè)計背后思想-創(chuàng)新互聯(lián)
文章來源:http://chinadenli.net/article8/goiip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、動態(tài)網(wǎng)站、標(biāo)簽優(yōu)化、定制開發(fā)、企業(yè)網(wǎng)站制作、網(wǎng)站維護

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化