2016-11-15 80 views
0

我有這個類:更好的封裝技術

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 = new Mail(/* Parameters */); 
$mailProvider = new Mailjet(); 
$mailProvider->send($mail->getContent(), $mail->getFrom /* etc */); 

回答

1

什麼其他消息?如果您想將內容和主題作爲文本發送,該怎麼辦?

作爲oop的指導原則,我嘗試使用SOLID。它提供了5個指導原則來幫助創建可維護的代碼。

這些原則有助於促進「應用程序如何改變,何時改變,需要改變什麼代碼」這一想法,目標是儘可能少地改變,以及儘可能少的認知儘可能加載,以執行更改。

一般來說,第一個選項似乎是一種不必要的耦合。郵件對象需要了解如何使用提供者?這是絕對必要的嗎?要添加提供者,我們可能需要更改Mail對象mail方法。 (即,如果提供商send需要附加參數

而第二個選項刪除1度耦合,並且只要求提供者可以對消息進行操作。添加消息字段或使提供者發送方法是不太可能需要更改郵件

哪個選項使客戶端上儘可能簡單(客戶端可以是你自己:))主觀上,我認爲第二個選項的作用是允許「郵件」團隊獨立於整合團隊工作,並且只要求mailjet團隊知道他們將會收到「郵件」界面,如果這樣做有任何意義......

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) { ... } 
    ... 
}