更好的封装技术

时间:2016-11-15 15:57:14

标签: php oop encapsulation

我有这堂课:

class Mail
{
    private $content;
    private $from;
    private $to;
    private $subject;

    public function __construct($content, $from, $to, $subject)
    {
        $this->content = $content;
        $this->from = $from;
        $this->to = $to;
        $this->subject = $subject;
    }
}

在某些时候我想发送一个邮件对象。内容可能使用html + css设置样式,在发送之前可能还有其他修改。我可以使用各种邮件提供商。什么选择会更好:

class Mail
{
    // ...

    public function mail(MailProvider $provider)
    {
        $provider->send($content, $subject, $to, $from);
    }
}

然后:

$mail = new Mail(/* Parameters */);
$mail->send(new Mailjet());

或者只是将getter添加到Mail类,然后执行:

$mail = new Mail(/* Parameters */);
$mailProvider = new Mailjet();
$mailProvider->send($mail->getContent(), $mail->getFrom /* etc */);

2 个答案:

答案 0 :(得分:1)

其他消息怎么样?如果您希望将内容和主题作为文本发送,该怎么办?

作为oop的指导原则,我尝试使用SOLID。它提供了5个指导原则来帮助创建可维护的代码。

这些原则有助于促进“应用程序如何变化,何时变更,需要更改哪些代码”的思想,目标是尽可能少地进行更改,并且认知负载很小,尽可能,是进行变革所必需的。

一般来说,第一个选项似乎是不必要的耦合。邮件对象需要了解如何使用提供程序?那是非常必要的吗?要添加提供程序,我们可能必须更改Mail对象mail方法。 (即,如果提供者send需要其他参数。

而第二个选项,删除1度耦合,并且只要求提供者可以对消息进行操作。添加消息字段或使用提供者发送方法不太可能需要更改邮件。

哪个选项在客户端上尽可能简单(客户端可以是你自己:) :)主观上,我认为第二个选项可以让“邮件”团队独立于集成团队工作,并且只要求mailjet团队知道他们将收到“邮件”界面,如果这有任何意义的话......

答案 1 :(得分:1)

问问自己:每个对象的责任是什么?然后答案变得有些明显了。

  • Mail代表邮件消息(强调代表
  • Mailjet:包含特定于与外部服务通信的代码

从这个描述中,类都不应该将代码保存到发送邮件。您可能想要的是第三类:

  • MailSender:使用Mail并使用特定服务发送

粗略勾画:

interface Mail {
    public function getContent();
    ...
}

interface MailServiceAdapter {
    public function send($content, $from, ...);
}

interface MailSender {
    public function send(Mail $mail);
}

class MailSenderImplementation implements MailSender {
    public function __construct(MailServiceAdapter $adapter) { ... }
    ...
}