別放棄寫可重用代碼!本文介紹三種修改現有代碼提高重用性的方法。
傳統 OO 方法缺陷增加重用難度。本文提供另類路徑三步驟。
類繼承缺乏精確性,想重用單一方法卻須繼承整個類 (含數據成員、其他方法),造成不必要負擔。父類修改影響子類,方法覆寫關係不明確。
**對策**:轉向過程式編程,將代碼從實例方法移出,形成全域可見的靜態通用方法 (或組織為獨立類的 public static 方法)。規則:只用輸入參數、只呼叫其他全域過程、不使用非區域變數。降低外部依賴,提高重用可能,結構更清晰。
**範例**:將 Polygon 實例方法委派給 pPolygon 靜態類:
class Polygon {
public int getPerimeter() { return pPolygon.computePerimeter(this); }
public boolean isConvex() { return pPolygon.isConvex(this); }
public boolean containsPoint(Point p) { return pPolygon.containsPoint(this, p); }
}
class pPolygon {
static public int computePerimeter(Polygon polygon) { ... }
static public boolean isConvex(Polygon polygon) { ... }
static public boolean containsPoint(Polygon polygon, Point p) { ... }
}
客戶代碼無需繼承 Polygon 即可重用功能。類別改為組織數據與實現多型 (介面)。
《Design Patterns》中 Strategy Pattern 類似,但將演算法封裝為物件仍有耦合與效能問題,可用 Flyweight Pattern 緩解,本質接近本步驟無狀態過程技術。
Allen Holub 指出:重用基礎在介面參數類型利用多型,而非類繼承。若方法參數皆為介面引用,該方法能操作編寫時尚不存在的類別物件。
**應用**:將步驟一產生的全域過程參數類別類型改為介面。例如 contains(Rectangle rect, ...) 改為 contains(Rectangular rect, ...),Rectangular 介面定義 getBounds()。所有實作 Rectangular 的類別皆可傳入。
**集合案例**:areAnyOverlapping(Collection rects) 遍歷集合檢查重疊,若無介面類型無法統一存取矩形區域,否則須知具體類型 (違反初衷)。
選能完整描述過程需求、額外負擔最少的介面。介面越簡單,實作類別越多,重用面越廣。
**範例**:areOverlapping(Window w1, Window w2) 僅需矩形座標,改為 areOverlapping(Rectangular r1, Rectangular r2),假設 Window 實作 Rectangular,即可重用於所有矩形物件。
**單一方法介面**:如排序比較器 SortComparison 僅定義 comesBefore(a,b),專為 sort(List, SortComparison) 服務,不宜他用。
三步驟結合 OO 技術形成新編程風格:提高重用性、內聚性,降低耦合與複雜度。不適用於本質難重用代碼 (如表示層 UI 建立、控制代碼)。