我有一个类来控制我在几个项目中使用的外部 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
相同的接口,这反过来意味着MyPaymentModule::doPayment()
应具有与PaymentModule::doPayment()
相同的参数。
我认为您想要创建一个为另一个类提供合理默认值的类并不少见,那么这里有什么常见的模式可以使用吗?当然,我可以选择两个完全独立的类,但我更喜欢一个仍然暗示两个类之间关系的解决方案......毕竟,它们将始终具有相同的方法,只是具有较少参数的方法。
你当前的类设计中是不可能的。我建议创建一个处理货币和语言的新类PaymentOptions。使用新方法setPayment选项或作为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;
}
}