首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

提升 Java 代碼復用性的三大核心策略:從繼承到組合與介面導向

     編輯:Java 相關知識

前言:繼承不是萬能藥

《Design Patterns》一書開宗明義:「多用組合,少用繼承」。繼承雖能復用代碼,卻造成強耦合、破壞封裝、且難以應對「單一方法復用」需求。本文深度解析三種實戰策略,幫助你寫出高內聚、低耦合、易測試的代碼。

策略一:靜態工具類封裝演算法 (提煉純函數)

痛點: 領域物件 `Polygon` 混雜了資料與演算法 (`getPerimeter`, `isConvex`),子類若只想復用 `containsPoint` 卻被迫繼承整個類別。

解法: 將演算法提煉為無狀態的 `static` 方法,放入專門的工具類 (命名慣例可用 `PolygonUtils` 或 `P` 前綴)。

// 原始類別:精簡為資料持有者
public class Polygon {
    private List<Point> vertices;
    // getter/setter...
}

// 工具類:封裝純演算法,零依賴、易測試
public final class PolygonUtils {
    private PolygonUtils() {} // 防止實例化
    
    public static int computePerimeter(Polygon p) { ... }
    public static boolean isConvex(Polygon p) { ... }
    public static boolean containsPoint(Polygon p, Point pt) { ... }
}

// 客戶端調用
int peri = PolygonUtils.computePerimeter(myPolygon);

優勢: 單一職責、無副作用、可獨立單元測試、支援函數式風格組合。

策略二:參數類型介面化 (面向介面編程)

痛點: 方法簽名綁定具體類別 `Rectangle`,無法處理 `Circle`、`Triangle` 等同樣擁有「邊界矩形」概念的物件。

解法: 定義 `Rectangular` 介面,方法參數改為介面類型。

public interface Rectangular {
    Rectangle getBounds(); // 契約:能提供邊界矩形
}

// 實作方
public class Circle implements Rectangular { ... }
public class Sprite implements Rectangular { ... }

// 演算法方法:完全不知情具體類別
public static boolean contains(Rectangular r, int x, int y) {
    return r.getBounds().contains(x, y);
}

// 集合場景更顯威力
public static boolean anyOverlap(Collection<? extends Rectangular> shapes) { ... }

關鍵: 介面應盡量精簡 (Interface Segregation Principle),只定義演算法真正需要的契約。

策略三:選擇最小必要介面 (介面隔離與角色介面)

痛點: `Window` 介面龐大,`areOverlapping(Window, Window)` 實際只需座標資訊,卻強迫呼叫端提供完整 `Window` 實作。

解法: 參數類型降級為最小介面 `Rectangular`,甚至為特定演算法定義專用單方法介面 (SAM / 函數式介面)。

// 排序演算法只需要「比較」能力
@FunctionalInterface
public interface Comparator<T> {
    int compare(T a, T b);
}

public static <T> void sort(List<T> list, Comparator<T> cmp) { ... }

// 調用時傳入 Lambda,零負擔
sort(list, (a, b) -> a.getWeight() - b.getWeight());

綜合對比與決策指南

策略適用場景核心原則代價
靜態工具類無狀態演算法、數學計算、字串處理純函數、無副作用失去多態擴展點
參數介面化多型處理、集合操作、框架擴展點依賴倒置、里氏替換介面爆炸風險
最小介面高階函數、策略模式、回調介面隔離、角色導向需設計良好契約

結語

這三大策略並非互斥,而是層層遞進:先提煉純函數 (策略一),再以介面解耦參數 (策略二),最後精簡介面至最小集 (策略三)。配合現代 Java 的 Lambda、Stream、Record,能構建出極具彈性的代碼庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved