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

PHP 多型 實戰詳解:介面驅動、策略模式與依賴注入

     編輯:PHP 綜合知識

多型 核心定義

「以不同形式、階段或類型出現,而不存在根本區別。」—— 同一介面/基類,不同具體實作,客戶端統一呼叫,無需關心具體類別。

基於介面的多型範例

<?php
interface Demo {
    const NAME = 'WangZhengYi';
    const AGE  = 25;
    public function fun1(): void;
    public function fun2(): void;
}

// 實作 A:學生身份
class One implements Demo {
    public function fun1(): void { echo self::NAME . " 就讀於中國傳媒大學\n"; }
    public function fun2(): void { echo self::NAME . " 的年齡是 " . self::AGE . "\n"; }
}

// 實作 B:實習生身份
class Two implements Demo {
    public function fun1(): void { echo self::NAME . " 在北京靈創眾和科技有限公司實習中\n"; }
    public function fun2(): void { echo self::NAME . " 去年的年齡是 24\n"; }
}

// 客戶端:只依賴 Demo 介面
function introduce(Demo $obj): void {
    $obj->fun1();
    $obj->fun2();
}

introduce(new One());  // 輸出學生資訊
introduce(new Two());  // 輸出實習資訊
?>

多型的三大支柱

支柱說明PHP 實現
介面/抽象基類定義統一契約interface / abstract class
繼承/實作具體類別實現契約implements / extends
向上轉型以父類型持有子物件參數型別宣告、陣列存儲、容器注入

實戰場景:付款策略多型

<?php
// 1. 統一介面
interface PaymentGateway {
    public function charge(float $amount, string $currency): bool;
    public function refund(string $transactionId): bool;
}

// 2. 多種實作
class StripeGateway implements PaymentGateway { /* ... */ }
class PayPalGateway implements PaymentGateway { /* ... */ }
class OfflineGateway implements PaymentGateway { /* ... */ }

// 3. 工廠根據配置產生具體實作
class GatewayFactory {
    public static function create(string $type): PaymentGateway {
        return match ($type) {
            'stripe'  => new StripeGateway(),
            'paypal'  => new PayPalGateway(),
            'offline' => new OfflineGateway(),
            default   => throw new InvalidArgumentException("Unknown gateway: $type"),
        };
    }
}

// 4. 業務邏輯完全不知具體閘道
class OrderService {
    public function __construct(private PaymentGateway $gateway) {}
    public function process(float $amt): bool {
        return $this->gateway->charge($amt, 'USD');
    }
}

// 5. 組裝 (可由 DI 容器自動完成)
$gateway = GatewayFactory::create(config('payment.default'));
$service = new OrderService($gateway);
$service->process(199.00);
?>

進階:運行期切換實作 (Strategy Pattern)

<?php
class ReportExporter {
    private ExportStrategy $strategy;

    public function setStrategy(ExportStrategy $s): void { $this->strategy = $s; }

    public function export(array $data): string {
        return $this->strategy->render($data);
    }
}

interface ExportStrategy {
    public function render(array $data): string;
}

class CsvStrategy implements ExportStrategy {
    public function render(array $data): string { /* CSV 邏輯 */ return "csv"; }
}
class PdfStrategy implements ExportStrategy {
    public function render(array $data): string { /* PDF 邏輯 */ return "pdf"; }
}
class ExcelStrategy implements ExportStrategy {
    public function render(array $data): string { /* Excel 邏輯 */ return "xlsx"; }
}

// 控制器根據請求參數動態切換
$exporter = new ReportExporter();
$exporter->setStrategy(match ($_GET['format'] ?? 'csv') {
    'pdf'   => new PdfStrategy(),
    'excel' => new ExcelStrategy(),
    default => new CsvStrategy(),
});
echo $exporter->export($reportData);
?>

多型帶來的架構價值

  • 開閉原則 (OCP):新增付款方式只需新增類別,不修改 OrderService
  • 依賴倒置 (DIP):高層模組依賴抽象 PaymentGateway,不依賴具體 StripeGateway
  • 可測試性:單元測試可注入 MockGateway 隔離外部依賴
  • 部署靈活:透過配置/環境變數切換實作,無需重新部署代碼

常見誤區

  1. 過度設計:只有單一實作且未來極低擴展可能時,介面反而增加複雜度
  2. 介面膨脹:單一介面方法過多違反 ISP,應拆分為細粒度介面
  3. 忽略 LSP:子類別行為違反父類別契約 (如拋出新例外、改變回傳型別) 會破壞多型

結語

多型不只是「同名方法不同行為」,更是「面向介面編程」的基石。掌握 interface + implements + 依賴注入,能讓 PHP 專案從「寫腳本」進化為「做架構」,實現高內聚、低耦合、可持續演進的代碼庫。

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