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

Java 結構型模式深度解析:適配器模式的類與物件兩種形式實戰詳解

     編輯:Java 相關知識

適配器模式是結構型模式中的經典之作,核心目的是將一個類的介面轉換為客戶端期望的另一個介面,使原本介面不兼容的類能夠協同工作。本文系統梳理適配器模式的類適配器(繼承式)與物件適配器(組合式)兩種形式,並通過 JDK 內建案例、幾何圖形轉換、寵物適配等生動範例,全方位剖析其實現細節與選型策略。

一、模式核心角色

角色說明類適配器物件適配器
Target(目標介面)客戶端期望的介面介面介面或抽象類
Adaptee(被適配者)現有、需適配的類類(被繼承)類(被組合)
Adapter(適配器)核心轉換邏輯繼承 Adaptee + 實作 Target組合 Adaptee + 實作 Target

二、類適配器模式(繼承式)

結構定義

類適配器類圖

代碼實現


package com.javapatterns.adapter.classAdapter;

public interface Target {
    void sampleOperation1();  // Adaptee 已有
    void sampleOperation2();  // Adaptee 缺失
}

public class Adaptee {
    public void sampleOperation1() { /* 現有實現 */ }
}

public class Adapter extends Adaptee implements Target {
    @Override
    public void sampleOperation2() {
        // 補充實現缺失的操作
    }
}

特性分析

  • 優點:可覆寫 Adaptee 方法;結構簡單,單一適配器類
  • 缺點:無法適配 Adaptee 子類(Java 單繼承限制);適配器與 Adaptee 強耦合

三、物件適配器模式(組合式)

結構定義

物件適配器類圖

代碼實現


package com.javapatterns.adapter;

public class Adapter implements Target {
    private final Adaptee adaptee;
    
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    
    @Override
    public void sampleOperation1() {
        adaptee.sampleOperation1(); // 委派
    }
    
    @Override
    public void sampleOperation2() {
        // 補充實現
    }
}

特性分析

  • 優點:一個適配器支援 Adaptee 及其所有子類;鬆耦合,符合組合優於繼承原則
  • 缺點:覆寫 Adaptee 方法較繁瑣(需先建立子類再適配)

四、JDK 內建適配器模式實例

1. AWT/Swing 事件適配器

java.awt.event 套件提供大量適配器類:

  • WindowAdapter、MouseAdapter、KeyAdapter 等

設計精髓:


// WindowListener 介面有 7 個方法
public interface WindowListener {
    void windowOpened(WindowEvent e);
    void windowClosing(WindowEvent e);
    // ... 共 7 個方法
}

// WindowAdapter 抽象類提供所有方法的空實現
public abstract class WindowAdapter implements WindowListener {
    public void windowOpened(WindowEvent e) {}
    public void windowClosing(WindowEvent e) {}
    // ... 全部空實現
}

使用方式:匿名內部類僅覆寫關心的方法


frame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
});

此處目標介面與來源介面相同,適配器的作用是免除實作所有方法的負擔——這是適配器模式的變體應用。

2. 類圖分析

SwingUI 與 WindowAdapter 類圖

五、實戰案例:方塊轉球體——幾何適配器

場景

現有 Cube 類(立方體),客戶端期望 BallIF 介面(球體),需計算表面積、體積、半徑。

物件適配器實現


package com.javapatterns.adapter.cube2ball;

public class Cube {
    private double width;
    public Cube(double width) { this.width = width; }
    public double calculateVolume() { return width * width * width; }
    public double getWidth() { return width; }
}

public interface BallIF {
    double calculateArea();      // 表面積
    double calculateVolume();    // 體積
    double getRadius();          // 半徑
    void setRadius(double radius);
}

public class MagicFinger implements BallIF {
    private final Cube adaptee;
    private double radius;
    private static final double PI = 3.14;
    
    public MagicFinger(Cube adaptee) {
        this.adaptee = adaptee;
        this.radius = adaptee.getWidth(); // 內切球半徑 = 立方體邊長
    }
    
    @Override public double calculateArea() {
        return 4 * PI * radius * radius;
    }
    @Override public double calculateVolume() {
        return 4.0/3.0 * PI * radius * radius * radius;
    }
    @Override public double getRadius() { return radius; }
    @Override public void setRadius(double radius) { this.radius = radius; }
}

數學含義:將立方體轉換為其內切球(最大能放入立方體的球)。

為何選物件適配器? 未來若新增 Tetrahedron(四面體)、Octahedron(八面體)等多面體,同一個 MagicFinger 類即可適配,無需為每種形狀建立專屬適配器類。

六、進階變體與實現討論

變體描述適用場景
目標介面省略Target 與 Adaptee 介面相同,適配器僅提供預設實現事件監聽器適配器
抽象適配器類Adapter 為 abstract class,提供部分預設實現需共享邏輯的適配器家族
參數化適配器適配器根據建構參數返回不同適配實例適配器非 Adaptee 子類、需動態選擇

七、選型決策指南


if (需適配 Adaptee 及其子類族)       → 物件適配器
else if (需覆寫 Adaptee 核心行為)      → 類適配器
else if (目標介面與來源介面相同)       → 目標介面省略變體(如 WindowAdapter)
else if (適配邏輯極簡、無狀態)         → 考慮靜態工廠方法替代
else                                    → 物件適配器(預設首選,符合組合優於繼承)

八、思考題與答案

  1. 貓適配狗:類適配器(Boyfriend extends Kittie implements Doggie)
  2. 形式識別:類適配器(繼承 Adaptee)
  3. 為何易懂:「男朋友必須裝成狗」——角色扮演隱喻降低認知門檻
  4. 形式差異影響:
    • 類適配器:換寵物 = 換男朋友(強綁定)
    • 物件適配器:同一男朋友可同時裝貓、裝狗、裝兔子(組合靈活)

九、總結

適配器模式是「介面不匹配」問題的標準解法。物件適配器因其鬆耦合、支援子類族、符合組合復用原則,應為預設首選;類適配器適用於需覆寫被適配者行為、且確定無子類擴展需求的場景。JDK 中的 WindowAdapter 則展示了「目標介面省略」這一實用變體。掌握這些變體與選型邏輯,能讓你在面對遺留系統整合、第三方庫適配、微服務介面轉換等場景時遊刃有餘。

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