【发布时间】:2020-12-26 22:47:05
【问题描述】:
我必须通过相关客户的 API 将发票发送给客户。
每个客户都可以选择联系方式(电子邮件、传真、短信...)。
我的问题是每次添加新的“联系人类型”时都会增加脚本的圈复杂度。
这是我的代码:
<?php
interface ExternalApi
{
public function sendByEmail();
public function sendByFax();
public function sendBySMS();
// more sending modes ...
}
class Api1 implements ExternalApi
{
public function sendByEmail()
{
echo __CLASS__." sending email<br>\n";
}
public function sendByFax()
{
echo __CLASS__." sending fax<br>\n";
}
public function sendBySMS()
{
echo __CLASS__." sending SMS<br>\n";
}
}
class Customer
{
public const EMAIL = 'email';
public const FAX = 'fax';
public const SMS = 'sms';
public const EMAIL_AND_FAX = 'email_and_fax';
public const PHONE = 'phone';
public const PLANE = 'plane';
public const BOAT = 'boat';
public const SATELITE = 'satelite';
public const CAB = 'cab';
// more contact types...
public ?string $contactType;
}
class Invoice
{
public Customer $customer;
public function __construct(Customer $customer)
{
$this->customer = $customer;
}
}
class InvoiceSender
{
private ExternalApi $api;
public function __construct(ExternalApi $api)
{
$this->api = $api;
}
public function send(Invoice $invoice)
{
switch($invoice->customer->contactType) {
case Customer::EMAIL :
$this->api->sendByEmail();
break;
case Customer::FAX :
$this->api->sendByFax();
break;
case Customer::SMS :
$this->api->sendBySMS();
break;
case Customer::EMAIL_AND_FAX:
$this->api->sendByEmail();
$this->api->sendByFax();
break;
// more cases ...
}
}
}
$customer = new Customer();
$customer->contactType = Customer::EMAIL_AND_FAX;
$invoice = new Invoice($customer);
$api = new Api1();
$invoiceSender = new InvoiceSender($api);
$invoiceSender->send($invoice);
如您所见,每次添加新的“联系人类型”时,InvoiceSender::send 的 switch 语句都会增加。
你知道哪种设计模式可以解决这个问题吗?
【问题讨论】:
-
将这些作为单独的类提取到关联数组中,然后通过
$invoice->customer->contactType从那里获取,并执行run()方法或它们之间的共同点。经典的strategy pattern,恰好有助于解决这里的圈复杂度。
标签: php design-patterns cyclomatic-complexity