PHP中的适配器设计模式实例

103 阅读1分钟

有时我们想使用一些类,但不幸的是,它们并不总是有我们需要的方法,或者它们随着时间的推移而改变,变得不兼容。在这种情况下,适配器模式可以帮助我们将不兼容的接口调整为兼容的接口,供我们的类使用。

例子

假设下面的TaxCalculator类不属于我们的团队,我们没有能力去改变它。我们所做的只是在我们的代码中使用它。

class TaxCalculator
{
    private $amount;
    private $rate;

    public function setAmountAndRate($amount, $rate)
    {
        $this->amount = $amount;
        $this->rate = $rate;

        return $this;
    }

    public function calculate()
    {
        return $this->amount * $this->rate;
    }
}

这就是我们如何使用它:

$taxCalculator = new TaxCalculator();
echo $taxCalculator->setAmountAndRate(100, 0.5)->calculate();

假设我们在很多地方使用了上面的代码,其他团队决定改变TaxCalculator类,使其看起来像下面的类:

class TaxCalculator
{
    private $amount;
    private $rate;

    public function setAmount($amount)
    {
        $this->amount = $amount;

        return $this;
    }

    public function getAmount()
    {
        return $this->amount;
    }

    public function setRate($rate)
    {
        $this->rate = $rate;

        return $this;
    }

    public function getRate()
    {
        return $this->rate;
    }

    public function calculate()
    {
        return $this->amount * $this->rate;
    }
}

正如你所看到的,我们下面的原始代码将被破坏,因为setAmountAndRate 方法已经被分割成两个不同的方法。

$taxCalculator = new TaxCalculator();
echo $taxCalculator->setAmountAndRate(100, 0.5)->calculate();

由于这些变化,我们现在必须使我们的原始代码看起来像下面的代码。

$taxCalculator = new TaxCalculator();
echo $taxCalculator->setAmount(100)->setRate(0.5)->calculate();

如果我们在应用程序的许多不同地方使用同一段代码,这将是一项艰巨的任务。你永远不知道,TaxCalculator类可能在将来再次被改变,我们最终也会重复自己。为了避免这种问题,我们可以在下面引入类。

interface AdapterInterface
{
    public function calculate();
}
 
class TaxCalculatorAdapter implements AdapterInterface
{
    public $taxCalculator;
 
    public function __construct(TaxCalculator $taxCalculator)
    {
        $this->taxCalculator = $taxCalculator;
    }
 
    public function calculate()
    {
        return $this->taxCalculator->getAmount() * $this->taxCalculator->getRate();
    }
}
 
$taxCalculator = new TaxCalculator();
$taxCalculator->setAmount(100)->setRate(0.5);
 
$taxCalculatorAdapter = new TaxCalculatorAdapter($taxCalculator);
echo $taxCalculatorAdapter->calculate();

如果TaxCalculator类再次改变,我们只需要改变TaxCalculatorAdapter本身一次,其他什么都不用做。