萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 適配器模式實戰教學:從接口適配到足球換人系統完整案例

模式定義與角色

適配器模式 將一個類的接口轉換為客戶期望的另一接口,使原本不兼容的類能協同工作。

角色說明本文對應
Target (目標接口)客戶端期望的接口SoccerPlayer
Adaptee (被適配者)現有不兼容接口Messi (中文方法名)
Adapter (適配器)轉換接口的核心類Adapter 實現 SoccerPlayer
Client (客戶端)使用目標接口測試代碼

適用場景

  1. 復用現有類但接口不匹配
  2. 創建可復用類與未知類協作
  3. 適配第三方庫/遺留代碼/外部 API

案例一:標準結構實現

<?php
// 目標接口
interface Target {
    public function simpleMethod1();
    public function simpleMethod2();
}

// 被適配者:只有 method1
class Adaptee {
    public function simpleMethod1() {
        echo "Adaptee simpleMethod1\n";
    }
}

// 適配器:組合模式持有 Adaptee
class Adapter implements Target {
    private $adaptee;
    
    public function __construct(Adaptee $adaptee) {
        $this->adaptee = $adaptee;
    }
    
    public function simpleMethod1() {
        return $this->adaptee->simpleMethod1(); // 委派
    }
    
    public function simpleMethod2() {
        echo "Adapter simpleMethod2\n"; // 自行實現
    }
}

// 客戶端
class Client {
    public static function main() {
        $adaptee = new Adaptee();
        $adapter = new Adapter($adaptee);
        $adapter->simpleMethod1();
        $adapter->simpleMethod2();
    }
}
Client::main();
// 輸出:
// Adaptee simpleMethod1
// Adapter simpleMethod2

案例二:足球換人系統(生動實戰)

領域模型

// 統一運動員接口
interface SoccerPlayer {
    public function attack();
    public function defense();
}

// 陣容球員
class Forward implements SoccerPlayer {
    public function attack() { echo "前鋒攻擊\n"; }
    public function defense() { echo "前鋒防守\n"; }
}

class Center implements SoccerPlayer {
    public function attack() { echo "中鋒攻擊\n"; }
    public function defense() { echo "中鋒防守\n"; }
}

// 明星球員:接口不兼容(中文方法名)
class Messi {
    public function 進攻() { echo "梅西進攻\n"; }
    public function 防守() { echo "梅西防守\n"; }
}

適配器讓梅西融入體系

class MessiAdapter implements SoccerPlayer {
    private $messi;
    
    public function __construct() {
        $this->messi = new Messi();
    }
    
    public function attack() {
        $this->messi->進攻(); // 方法名映射
    }
    
    public function defense() {
        $this->messi->防守();
    }
}

客戶端調用

$player1 = new Forward();
echo "前鋒上場:\n";
$player1->attack();
$player1->defense();

echo "\n---\n梅西上場:\n";
$messi = new MessiAdapter();
$messi->attack();
$messi->defense();

/*
前鋒上場:
前鋒攻擊
前鋒防守

---
梅西上場:
梅西進攻
梅西防守
*/

兩種適配器變體

實戰擴展:雙向適配器

// 當需要雙向轉換時
interface LegacyLogger {
    public function log(string $msg);
}

interface ModernLogger {
    public function info(string $msg);
    public function error(string $msg);
}

class BiDirectionalAdapter implements LegacyLogger, ModernLogger {
    private $legacy;
    private $modern;
    
    public function __construct($legacy = null, $modern = null) {
        $this->legacy = $legacy;
        $this->modern = $modern;
    }
    
    // Legacy → Modern
    public function log(string $msg) {
        $this->modern?->info($msg);
    }
    
    // Modern → Legacy
    public function info(string $msg) {
        $this->legacy?->log("[INFO] $msg");
    }
    public function error(string $msg) {
        $this->legacy?->log("[ERROR] $msg");
    }
}

最佳實踐建議

  1. 優先組合: 對象適配器靈活解耦
  2. 2. 接口隔離: 適配器只實現目標接口需求子集 3. 命名規範: 類名以 Adapter 結尾,方法名保持目標接口語義 4. 異常轉換: 適配層統一異常類型,隱藏實現細節 5. 文檔說明: 註釋被適配者來源、版本、映射邏輯

總結

適配器模式是**系統集成、遺留重構、第三方庫接入**的利器。核心思想:**不修改現有代碼,通過中間層轉換接口**。PHP 中採用組合實現對象適配器,配合介面契約,實現高內聚低耦合的擴展架構。

copyright © 萬盛學電腦網 all rights reserved
類型實現方式優點缺點
對象適配器組合 + 委派(本文兩例)可適配子類、靈活、符合合成復用需重寫委派方法
類適配器多重繼承 (PHP 用 traits 模擬)可覆寫 Adaptee 行為PHP 不支援多重繼承、耦合度高