Java進階 | 從整體上觀察物件導向

知了一笑發表於2021-08-10

一、物件導向

物件導向是Java程式設計中最核心的思想,基本特徵:繼承、封裝、多型。

1、特徵之封裝

將結構、資料、操作封裝在物件實體中,使用時可以不關注物件內部結構,只能訪問開放許可權的功能入口,從而降低程式耦合程度,提供安全性和可持續維護性。

public class Concept01 {
    public static void main(String[] args) {
        Student student = new Student("張三","高三",29f);
        student.conclusion();
    }
}
class Student {
    private String name ;
    private String grade ;
    private Float score ;
    public Student(String name, String grade, Float score) {
        this.name = name;
        this.grade = grade;
        this.score = score;
    }
    public void conclusion (){
        System.out.println("姓名:"+this.getName());
        System.out.println("年級:"+this.getGrade());
        System.out.println("分數:"+this.getGrade());
        if (this.getScore() >= 100.0f){
            System.out.println("評語:本學期優等生");
        } else {
            System.out.println("評語:本學期潛力股");
        }
    }
}

案例描述Student的學期總結,通過構造方法構建具體的學生物件,並且只通過conclusion方法獲取學生學期評價。

2、特徵之繼承

子類除了提供自身的能力之外,還可以通過繼承的方式獲取父類開放的屬性和方法,以增強自身的功能。

public class Concept02 {
    public static void main(String[] args) {
        // 判斷 Digital 是 Phone 父類
        System.out.println(Digital.class.isAssignableFrom(Phone.class));
    }
}
class Digital {}
class Phone extends Digital{}

這裡通過isAssignableFrom方法判斷Digital是Phone父類。

3、特徵之多型

不同主體類對同一個動作給出不同的實現方式,多型也是Java描述設計模式的常用手段,最直接的作用就是程式解耦。

public class Concept03 {
    public static void main(String[] args) {
        Animal animalDog = new Dog();
        Animal animalCat = new Cat();
        animalDog.voice();
        animalCat.voice();
    }
}
class Animal {
    public void voice () {
        System.out.println("Animal ... voice");
    }
}
class Dog extends Animal {
    @Override
    public void voice() {
        System.out.println("Dog ... Wang wang");
    }
}
class Cat extends Animal {
    @Override
    public void voice() {
        System.out.println("Cat ... Meow meow");
    }
}

通常動物都有發出聲音的能力,但是不同動物聲音不同,這裡基於多型實現,不同動物的聲音特徵。

二、關係圖譜

在瞭解物件導向之後,還需要理解一下基礎的關係模型,在實際的業務中都是基於這些基礎的關係解決場景問題。

1、繼承與實現

繼承關係:強調屬性和方法從父類向子類的傳承。實現關係:強調描述抽象和具體實現的邏輯。

/**
 * 繼承
 */
class classA {}
class classB extends classA {}
interface interfaceA {}
interface interfaceB extends interfaceA {}
/**
 * 實現
 */
class classC implements interfaceA,interfaceB{}

2、依賴與關聯

依賴關係:常用來描述方法區域性變數或者入參,即類的方法中呼叫了另一個類。關聯關係:類的成員變數是另一個類,比如常見的一對一,一對多關係。

/**
 * 依賴
 */
class RelyA {}
class RelyB {
    public void depend (RelyA rely){}
}
/**
 * 關聯
 */
class AssociateA {}
class AssociateB {
    private AssociateA associateA ;
}

3、組合與聚合

聚合關係:描述整體與部分的關係,但是部分不需要依賴整體存在。組合關係:描述整體與部分的關係,但是部分需要依賴整體存在。

/**
 * 聚合
 */
class ElementA {}
class ElementB {}
class Aggregation {
    private ElementA elementA ;
    private ElementB elementB ;
}
/**
 * 組合
 */
class PortionA{}
class PortionB{}
class Composition {
    private PortionA portionA ;
    private PortionB portionB ;
}

三、模式與原則

在面對複雜業務時,可以時常參考設計模式和基本原則,以此設計合理的業務結構,實現程式碼的高內聚低耦合,但是在一些特定場景下,也要果斷的突破這些模板或原則,可以更好的支撐業務。

1、設計模式

建立模式

抽象物件例項化的建立過程,對不同型別的物件提供高效的管理方式與合理的建立手段。

  • 單例模式
  • 原型模式
  • 工廠模式
  • 建造者模式

結構模式

設計類的組裝模式,合理的物件結構,有利於支援業務的持續迭代,結構會直接影響程式碼的可持續維護性。

  • 代理模式
  • 外觀模式
  • 介面卡模式
  • 裝飾者模式
  • 組合模式
  • 享元模式
  • 橋樑模式

行為模式

行為模式涉及物件職責定義,通訊協作,和最具體的業務邏輯實現,明確程式執行時的流程軌跡。

可以基於繼承或實現的方式控制不同類的行為職責,即頂層抽象控制行為,下層逐級做具體邏輯實現;或者直接聚合管理責任物件,做統一分配。

  • 觀察者模式
  • 模版方法模式
  • 策略模式
  • 命令模式
  • 調停者模式
  • 備忘錄模式
  • 直譯器模式
  • 迭代器模式
  • 狀態模式
  • 責任鏈模式
  • 訪問者模式

2、基本原則

  • 開閉原則:在做程式碼結構設計時,應該考慮對擴充套件開放,對修改關閉,抽象思維搭建結構,具體實現擴充套件細節。

  • 單一職責:一個類應該只負責一項職責;減少程式碼一處變更引起的程式大規模改動情況,降低類的複雜度;

  • 介面隔離:每一個介面應該是一種角色;儘量避免具體實現類中用不到但是又必須實現的方法;

  • 依賴倒轉:上層模組不應該依賴下層模組,抽象邏輯不應該依賴具體細節,即中心思想是面向介面程式設計。

  • 里氏替換:繼承時遵循里氏替換原則,子類中儘量不要重寫父類的方法,可以擴充套件父類的功能;

  • 迪米特原則:最少知道原則即類物件對其依賴的類知道的越少越好,以此降低耦合程度;

  • 組合/聚合複用:新物件應使用部分已有的物件,使其成為新物件組成部分,實現已有功能的複用,以此降低單個類的複雜程度。

四、業務應用

在業務開發中,很多複雜的邏輯都是基於物件導向的思想做的設計和具體實現,但是在實際上業務是不斷變化的,所以不管是常用的Mvc模式,或者領域設計,只要經過多個版本迭代,多人蔘與的開發,到最後程式碼在邏輯層面都會讓人著迷。

也就是常說的一種現象:新人重構,老人不斷修復問題,然而鐵打的問題,流水的開發,但凡經歷過重構的同學都知道,所謂的大規模重構很難徹底解決問題,甚至這是個迴圈動作。所以業務程式碼更多是在那個版本週期內是合理的,站在一個開發的角度,這裡也可以理解為筆者個人角度,通常從下面幾個角度去思考具體的業務開發:

  • 規範約束

這是個人認為業務工程中最重要的基礎,不管業務如何複雜,都離不開與之相應的資料增刪改查,所以對常規基礎操作做好統一程式碼風格管理,這樣有助於別人快速理解整體結構和邏輯。

這裡風格指:介面命名,引數,元件,中介軟體等統一,以持久層為例,避免多個元件混用的情況,如果是週期相對較長的專案,經常看到單是分頁查詢的實現邏輯都有多種情況。

  • 可複用性

易變是業務本身的特點,所以高度複用的業務程式碼本身就存在很大的限制,例如常見的很多方法,為了適配各種場景,不斷擴充套件入參,然後有些特殊業務也會進行特殊傳參。

還有一些開發常說的,能用一個介面實現,絕對不使用兩個介面,看似很有個性,實際已經走在挖坑的路上,多個功能請求同一個介面,即意味著任何介面的改動都要考慮很多邏輯的適配。

所以從上層向下看,不必過度考慮複用,從下向上看,底層的改動相對較少,應該考慮複用。

  • 業務分層

從專案生命週期的角度思考,業務是一個迭代的過程,不需要過度前衛的設計,專案的生命週期是多久沒人知道,最穩妥的做法是快速迭代,產品和技術工程能快速穩定的支撐業務發展即可。

經典的業務分層管理是快速迭代的基本支撐,例如常用的Mvc模式,在複雜的業務場景下可以再次細化管理,或者向領域設計靠近。

  • 流程分段

業務可以理解為流程管理,小的流程通常service中可以直接處理,但是複雜流程則十分講究設計,一個基礎思想就是分段管理,比較經典的案例就是下單:構建結算頁面時初始化訂單-支付時訂單提交-支付成功才會執行訂單。

  • 細節問題

邏輯上的細節要持續追求嚴謹,業務實現手段和思路適當放寬,流程經得起考驗,底層實現合理的複用,元件選擇上應該站在高緯度,就基本足以。

五、原始碼地址

GitHub·地址
https://github.com/cicadasmile/java-base-parent
GitEE·地址
https://gitee.com/cicadasmile/java-base-parent

閱讀標籤

Java基礎】【設計模式】【結構與演算法】【Linux系統】【資料庫

分散式架構】【微服務】【大資料元件】【SpringBoot進階】【Spring&Boot基礎

資料分析】【技術導圖】【 職場

相關文章