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

PHP 面向介面編程實戰:計算器案例演示介面多態與依賴注入

     編輯:PHP 綜合知識

面向介面編程是「依賴倒置原則」的核心體現:高層模塊不應依賴低層模塊,二者都應依賴其抽象。本文通過一個計算器案例,展示 PHP 介面如何實現運算邏輯的多態切換、耦合解耦與測試友好。

核心介面定義

<?php
interface Calculator {
    public function calculate(float $a, float $b): float;
}
?>

多態實現:五種運算策略

<?php
class Addition implements Calculator {
    public function calculate(float $a, float $b): float {
        return $a + $b;
    }
}

class Subtraction implements Calculator {
    public function calculate(float $a, float $b): float {
        return $a - $b;
    }
}

class Multiplication implements Calculator {
    public function calculate(float $a, float $b): float {
        return $a * $b;
    }
}

class Division implements Calculator {
    public function calculate(float $a, float $b): float {
        if ($b == 0) throw new DivisionByZeroError("除數不能為零");
        return $a / $b;
    }
}

class Modulo implements Calculator {
    public function calculate(float $a, float $b): float {
        return $a % $b;
    }
}
?>

耦合設計模式:適配器模式整合第三方邏輯

場景:引入一個「外星計算器」,其介面為 compute($x, $y),不符合我們的 Calculator 介面。

<?php
// 第三方類(無法修改)
class AlienCalculator {
    public function compute(float $x, float $y): float {
        return sqrt($x * $x + $y * $y); // 異星算法:勾股定理
    }
}

// 適配器:實現我們的介面,委派給第三方
class AlienCalculatorAdapter implements Calculator {
    public function __construct(private AlienCalculator $alien) {}
    
    public function calculate(float $a, float $b): float {
        return $this->alien->compute($a, $b);
    }
}
?>

高層模塊:測試類依賴介面而非具體實現

<?php
class CalculatorTester {
    private float $operand1;
    private float $operand2;
    
    public function __construct(float $a, float $b) {
        $this->operand1 = $a;
        $this->operand2 = $b;
        echo "

計算器測試器初始化

"; echo "操作數: {$this->operand1}, {$this->operand2}
"; } // 關鍵:參數類型聲明為介面 public function test(Calculator $calculator): string { $result = $calculator->calculate($this->operand1, $this->operand2); $className = get_class($calculator); return "[$className] 計算結果: $result
"; } } ?>

客戶端代碼:運行時動態注入

<?php
require_once 'Calculator.php';
require_once 'Operations.php';
require_once 'Adapter.php';
require_once 'CalculatorTester.php';

$tester = new CalculatorTester(10, 3);

// 1. 測試加法
$tester->test(new Addition());

// 2. 測試減法
$tester->test(new Subtraction());

// 3. 測試適配器(外星計算器)
$tester->test(new AlienCalculatorAdapter(new AlienCalculator()));

// 4. 運行時根據配置選擇
$operations = [
    'add' => new Addition(),
    'sub' => new Subtraction(),
    'mul' => new Multiplication(),
    'div' => new Division(),
    'mod' => new Modulo(),
    'alien' => new AlienCalculatorAdapter(new AlienCalculator()),
];

$selected = $_GET['op'] ?? 'add';
if (isset($operations[$selected])) {
    echo $tester->test($operations[$selected]);
} else {
    echo "未知操作: $selected";
}
?>

進階:依賴注入容器管理

<?php
// 簡易容器
class Container {
    private array $bindings = [];
    private array $instances = [];
    
    public function bind(string $abstract, callable $concrete): void {
        $this->bindings[$abstract] = $concrete;
    }
    
    public function singleton(string $abstract, callable $concrete): void {
        $this->bind($abstract, function() use ($concrete) {
            return $this->instances[$abstract] ??= $concrete($this);
        });
    }
    
    public function make(string $abstract) {
        if (!isset($this->bindings[$abstract])) {
            throw new Exception("未綁定: $abstract");
        }
        return $this->bindings[$abstract]($this);
    }
}

// 配置綁定
$container = new Container();
$container->bind(Calculator::class . ':add', fn() => new Addition());
$container->bind(Calculator::class . ':sub', fn() => new Subtraction());
$container->singleton(Calculator::class . ':alien', fn() => new AlienCalculatorAdapter(new AlienCalculator()));

// 使用
$calculator = $container->make(Calculator::class . ':add');
echo $tester->test($calculator);
?>

核心優勢總結

原則體現收益
介面隔離Calculator 只定義 calculate實現類職責單一,易擴展新運算
依賴倒置CalculatorTester 依賴介面可注入任意實現,無需修改測試器
開閉原則新增運算只需新增類不修改現有代碼即可擴展功能
里氏替換所有實現可互換使用運行時動態切換,支援策略模式
適配器模式整合不兼容介面復用第三方代碼,不污染核心領域模型

單元測試友好性演示

<?php
// 測試時輕松 Mock 介面
class MockCalculator implements Calculator {
    public function __construct(private float $fixedResult) {}
    public function calculate(float $a, float $b): float {
        return $this->fixedResult;
    }
}

class CalculatorTesterTest extends PHPUnit\Framework\TestCase {
    public function testDisplaysResult() {
        $tester = new CalculatorTester(10, 5);
        $mock = new MockCalculator(42.0);
        $output = $tester->test($mock);
        $this->assertStringContainsString('42', $output);
    }
}
?>

總結

這個計算器案例雖小,但完整演示了面向介面編程的精髓:

  1. 定義契約:interface Calculator 規範「能做什麼」
  2. 多態實現:各運算類實現契約,邏輯內聚
  3. 依賴抽象:高層 CalculatorTester 只認介面
  4. 運行時綁定:客戶端決定具體實現,支援配置驅動
  5. 適配外部:適配器橋接不兼容介面,保護核心模型純淨
  6. 測試友好:輕松 Mock 介面進行單元測試

在實際專案中,將此模式應用於:支付網關、存儲驅動、消息隊列、認證提供者、日誌處理器、導出格式 等所有「多實現、可切換、可擴展」的場景。配合依賴注入容器,即可構建高內聚、低耦合、可測試的現代 PHP 應用架構。

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