我使用什么OOP模式来提供默认值而不违反Liskov替换原则

时间:2015-03-16 07:46:51

标签: php oop

我有一个类来控制我在几个项目中使用的外部API(简化示例):

class PaymentModule
{
  public function doPayment($customer_name, $currency, $language)
  {
    curl_setopt(POSTFIELDS, array($customer_name, $currence, $language));
    curl_exec();
  }
}

现在在一个特定的项目中,我想“包装”它并为我在这里不使用的许多参数提供合理的默认值。

所以我想,我只会extend这个类,让我的IDE覆盖所有方法,然后删除我不使用的参数,如下所示:

class MyPaymentModule extends PaymentModule
{
  public function doPayment($customer_name)
  {
    $language = get_current_language();
    parent::doPayment($customer_name, 'EUR', $language);
  }
}

正如我现在所知(由于PHP严格的标准),这违反了Liskov替换原则,即在OOP中MyPaymentModule通常与PaymentModule具有相同的接口,这反过来意味着{ {1}}应具有与MyPaymentModule::doPayment()相同的参数。

我认为你想要创建一个为另一个提供合理默认值的类并不常见,所以这里有什么常用模式可供使用吗? 当然我可以选择两个完全独立的类,但我更喜欢一个仍然暗示两个类之间关系的解决方案......毕竟它们总是有相同的方法,只有一个 less 参数。

1 个答案:

答案 0 :(得分:0)

目前的课堂设计无法实现。 我建议创建一个处理货币和语言的新类PaymentOptions。 使用新方法setPaymentOptions或doPayment的可选参数将选项传递给doPayment。

这样的事情应该有效

class PaymentModule {

    /**
     * @var PaymentOptions
     */
    private $paymentOptions = null;

    function doPayment($customer_name, PaymentOptions $options = null) {
        if ($options == null) {
            $options = $this->paymentOptions;
        }
        if ($options == null) {
            throw new Exception('...');
        }

        //...
    }

    /**
     * @return PaymentOptions
     */
    public function getPaymentOptions()
    {
        return $this->paymentOptions;
    }

    /**
     * @param PaymentOptions $paymentOptions
     */
    public function setPaymentOptions($paymentOptions)
    {
        $this->paymentOptions = $paymentOptions;
    }

}

class MyPaymentModule extends PaymentModule {

    function doPayment($customer_name, PaymentOptions $options = null)
    {
        //...
    }

}

class PaymentOptions {
    private $currency;
    private $language;

    /**
     * @return mixed
     */
    public function getCurrency()
    {
        return $this->currency;
    }

    /**
     * @param mixed $currency
     */
    public function setCurrency($currency)
    {
        $this->currency = $currency;
    }

    /**
     * @return mixed
     */
    public function getLanguage()
    {
        return $this->language;
    }

    /**
     * @param mixed $language
     */
    public function setLanguage($language)
    {
        $this->language = $language;
    }
}