【问题标题】:Where to put the email sending?发邮件的地方放在哪里?
【发布时间】:2016-12-16 09:50:54
【问题描述】:

有一个“新闻”系统,当添加一个“新”时,也应该发送一封电子邮件。

class ModelNews extends NewsORM
{
    public function add ($new)
    {
        INSERT INTO newstable
    }
}

但我还需要发送电子邮件,所以:

class ModelNews extends NewsORM
{
    public function add ($new)
    {
        INSERT INTO newstable
        mail->send
    }
}

但它看起来很奇怪。好像违反了SRP

【问题讨论】:

  • 也许应该在Controller而不是模型中进行管理? if ($model->add($new)) $mail->send();
  • 但是可以从任何地方添加新的“新闻”,这样我应该总是调用控制器。那行不通

标签: php email orm single-responsibility-principle


【解决方案1】:

您可以编写一个侦听器/调度器,它可以在数据库中查找新记录,然后发送电子邮件。

class ModelNews extends NewsORM
{
    public function add ($new)
    {
        INSERT INTO newstable
    }
}

class SendNews extends NewsListener
{
     public function listen($news) {
        mail-> send
     }
}

因此不违反 SRP

【讨论】:

  • 但封装确实 :) 违反了封装。见:stackoverflow.com/questions/11619680/…
  • 我同意。只要不修改核心状态就不会造成任何伤害。但是,我会让实施者选择愿意违反的原则:-)
【解决方案2】:

看起来违反了 SRP

确实如此。当你需要做多件事时,你可以应用开闭原则,解耦一切。

interface AddNews
{
    public function add($new);
}

class SaveNews extends NewsORM implements AddNews
{
    public function add($new)
    {
        // INSERT INTO newstable
    }
}

class SendNews extends NewsORM implements AddNews
{
    public function add ($new)
    {
        //mail->send
    }
}

class AggregatorNews implements AddNews
{ 
    private $news = []; 

    public function addNews(AddNews $news)
    { 
        $this->news[] = $news; 
    } 

    public function add($new)
    { 
        foreach ($this->news as $obj) { 
            $obj->add($new); 
        } 
    } 
} 

那么你可以这样使用它:

$news = new AggregatorNews();
$news->addNews(new SaveNews);
$news->addNews(new SendNews);

$news->add('bla bla');

【讨论】:

  • 为什么不直接扩展 ORM?为什么要将它们添加到列表中?
【解决方案3】:

创建一个新的 sendEmail 函数并将代码放在那里。

当你需要它时。在整个应用程序中调用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2011-04-08
    • 1970-01-01
    相关资源
    最近更新 更多