1. 程式人生 > >java面向物件六大原則

java面向物件六大原則

面向物件特點:

        1:將複雜的事情簡單化。

        2:面向物件將以前的過程中的執行者,變成了指揮者。

        3:面向物件這種思想是符合現在人們思考習慣的一種思想。

什麼是面向物件呢?

        面向物件是一種程式設計思想,這種程式設計思想凸顯物件在程式設計過程中的重要作用。

        簡單的說就是讓物件成為類與類之間的“通訊”的橋樑,通過物件使類之間形成有機的整體。

        Java語言中的物件是對現實世界中物件的模擬,現實中的物件存在於現實生活中,Java語言中的物件存在於計算機記憶體中,Java語言中的物件又稱為例項。

        Java中將現實物件中的資訊靜態特徵稱為屬性(也叫全域性變數),將現實物件中的功能動態特徵

稱為方法。

        過程和物件在我們的程式中是如何體現的呢?過程其實就是函式;物件是將函式等一些內容進行了封裝。

面向物件與面向過程的區別

        面向物件是從巨集觀方面思考問題,而面向過程可以說是從細節處思考問題。

        面向物件程式語言以物件為中心,以訊息為驅動,即程式=物件+訊息;而面向過程程式語言則以過程為中心,以演算法為驅動,即程式=演算法+資料

        在面向物件中,也存在面向過程。

 

面向物件6大原則

1、單一職責原則

定義:

        一個類只負責一項職責。

優點

        降低類的複雜度,一個類只負責一個職責,其邏輯一定會比一個類負責多項職責要簡單,同時也易於維護

        提高類的可讀性,提高系統的可維護性

        低變更所帶來的風險;系統的變更是必然的,如果單一職責原則遵守的好,那麼當修改一個功能時可以顯著降低對其他功能的影響

  雖說我們要遵守單一職責原則,但是也不是說死板的對每一個細節都嚴格遵守,也要視情況而定:如果一個類的邏輯非常簡單且可以保證變化極小,此時可以在程式碼級別上違反單一職責原則;另外當一個類中方法很少時,也可以在方法的級別上違反這一原則。(這裡我這麼理解單一職責原則:分為兩個層次,最高層次是類的層次,其次是方法層次上)但是如果一個類相對龐大,類中方法較多時,一定要遵守單一職責原則;寧願在第一次擴充套件時花費精力完成重構,也要遵守這一原則,否則會給以後的擴充套件帶來不可預估的災難!

2、裡式替換原則

定義

        如果對每一個型別為T1的物件o1,都有型別為T2的物件o2,使得以T1定義的所有程式P在所有的物件o1都替換為o2時,程式P的行為沒有發生變化;那麼型別T2是型別T1的子型別

        所有引用基類的地方必須可以透明的使用其子類的物件

通俗的講就是:一個軟體實體如果使用的是一個父類的話,那麼一定適用於其子類,而且它察覺不出父類物件和子類物件的區別。也即在軟體裡面把父類都替換成他的子類,程式的行為沒有發生任何變化。

  繼承包含這樣一層含義:父類中凡是已經實現好的方法(區別於抽象方法),實際上是在設定一系列的規則和契約,雖然它並不要求所有的子類都必須強制遵守這些規則,但是如果子類任意對這些非抽象方法進行重寫,就會對整個繼承體系造成破壞。裡式替換原則主要就是想表達這一層含義。

  當然如果你非要重寫父類的非抽象方法,這時應該採用這樣的方式:原來的父類和子類都繼承自一個更通用的基類,原有的繼承關係去掉,轉而採用依賴、聚合、組合等關係來替代。

  更通俗的說就是:子類可以擴充套件父類的功能,但是不能修改父類原有的功能;具體有以下4中含義:

        子類可以實現父類的抽象方法,但是不能覆蓋父類的非抽象方法

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

        當子類的方法過載父類的方法時,方法的前置條件(形參)要比父類方法的輸入方法更寬鬆

        當子類實現父類的抽象方法時,方法的後置條件(即方法返回值)要比父類更嚴格

3、依賴倒轉原則

定義:

        抽象不應該依賴細節,細節應該依賴於抽象(說白了就是要針對介面程式設計,不要對實現程式設計);也即:

        高層模組不應該依賴於底層模組,二者都應該依賴於抽象;

        抽象不應該依賴於細節,細節應該依賴於抽象

        依賴倒轉原則基於這樣一個事實:相對於細節實現中的多變性,抽象的東西要穩定的多;以抽象為基礎搭建起來的架構比以細節為基礎搭建起來的架構要穩定的多。抽象一般指的是介面、抽象類,細節就是具體的實現類。使用抽象的目的是制定好規範和契約,而不要涉及具體的實現,把細節交給他們的實現類來完成。

  依賴倒轉原則的核心就是面向介面程式設計,傳遞依賴關係有三種方式:介面傳遞、構造方法傳遞、setter傳遞(如果用過spring框架,那麼對傳遞一定會很熟悉)。在實際的開發中我們主要通過以下幾點來較好的遵守依賴倒轉原則:

        底層模組儘量都要有抽象類或介面,或兩者都有

        變數的宣告型別儘量是抽象類或介面

        使用繼承時要遵循裡式替換原則

  遵循依賴倒轉原則可以降低類之間的耦合性,提高系統穩定性,降低修改造成的風險。同時,採用依賴倒轉原則給並行開發帶來了極大的便利,參與開發的人越多、專案越龐大依賴倒轉原則意義和好處就越明顯。當前比較流行的TDD開發模式就是依賴倒置原則非常成功的應用。

4、迪米特法則

定義(也叫最少知道原則)

        如果兩個類不必直接通訊,那麼這兩個類就不應當發生直接的相互作用。如果一個類需要呼叫另一個類的方法,可以通過第三方來轉發這個呼叫

一個物件應該保持對其他物件最少的瞭解

  通俗的來講,就是一個類對自己以來的類知道的越少越好;也就是說對於被依賴的類來說,無論邏輯多麼複雜,都應當把邏輯封裝在內部,對外除了提供public方法之外,不洩露其他任何資訊。再通俗來說:迪米特法則就是‘只與直接的朋友通訊’。那麼什麼是直接的朋友呢:每個物件都會與其他物件有耦合關係,只要兩個物件間出現耦合關係,我們就說兩個物件之間是朋友關係。而耦合的方式有很多,依賴、關聯、聚合、組合都是耦合關係;其中,我們稱出現成員變數、方法引數、方法返回值中的類為直接朋友,而出現在區域性變數中的類則是間接朋友關係。也就是說陌生的類最好不要作為區域性變數的形式出現在類的內部。

  迪米特法則的初衷是降低類之間的耦合,但是凡事都有一個度,雖然可以避免與非直接類之間的通訊,但是要通訊就必須通過一箇中介來發生關係;而過分的使用迪米特法則,就會產生大量這樣的中介和傳遞類,導致系統的複雜度增加。所以在使用迪米特法則時,要反覆權衡,既要做到結構清晰又要高內聚低耦合。

5、開放-封閉原則

定義:

        一個軟體實體(如類、模組、函式等)應該對擴充套件開放,對修改關閉;即可以擴充套件但是不能修改

當軟體需要變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不能通過修改已有程式碼來實現變化。

  開放-封閉原則是面向物件設計中最基礎的原則,它指導我們如何建立穩定、靈活的系統。但是他也是這幾個模式中定義最為模糊的一個,在初接觸它時,總給你一種無處下手的感覺,因為它太虛了。但是當把其他原則還有23中設計模式通讀了一遍之後,我發現可以這麼理解它:開放-封閉原則是戰略,而其他的幾個原則以及設計模式就是具體的戰術;如何實現開放-封閉原則呢?要想實現一個戰略,就必須要制定合適的戰術:即,通過較好的遵守其他幾個原則以及通過合適的設計模式,最終實現一個軟體很好的開發-封閉原則。

6、介面隔離原則

  客戶端不應該依賴它不需要的介面,一個類對另一個類的依賴應該建立在最小的介面上。

  可以這麼理解:如果介面過於臃腫,那麼實現他的類不管用不用的到,都必須實現介面中所有的方法,這顯然是不好的設計;這時候就需要遵循介面隔離原則對臃腫的介面進行拆分。他的原則就是:儘量建立單一的介面,儘量細化介面,介面中的方法儘量少。也就是說,我們要為各個類建立專用的介面,而不是試圖去建立一個很龐大的介面共所有依賴他的類去呼叫。

  這裡介面隔離原則與單一職責原則也有一定的區別,主要從以下方面來看:

單一職責原則注重的是職責,而介面隔離注重的是對介面依賴的隔離;

單一職責原則主要約束的是類,其次才是介面和方法,它主要針對的是程式中實現的細節;而介面隔離原則主要針對介面和抽象,針對程式框架的構建。

  但是在使用介面隔離原則時也一定要適度,一定要注意:

介面儘量小,但是也要有限度。如果介面過小,會造成介面過多,而導致增加設計的複雜度。

為依賴介面的類定製服務,只暴露給呼叫他的類所需要的方法,他不需要的方法則要隱藏起來。只有專注的為一個模組提供定製服務,才能建立最小的依賴關係。

轉載自:https://blog.csdn.net/niudasheng/article/details/80595217