1

There is a "news" system, when a "new" is added, an email should be sent too.

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

but I also need to send an email, so:

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

but it looks odd. It looks like SRP is violated

John Smith
  • 6,129
  • 12
  • 68
  • 123
  • 1
    Maybe it should be managed in the Controller instead of the model? if ($model->add($new)) $mail->send(); – Jmunoz Dev Dec 16 '16 at 09:56
  • but a new "news" can be added from anywhere, and that way I should always call the controller. That wouldnt work – John Smith Dec 16 '16 at 10:01

3 Answers3

2

You could write a listener/scheduler that could look for new records in the database and then send the email.

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

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

Thus SRP is not violated

JWS
  • 158
  • 1
  • 8
  • but encapsulation does :) encapsulation violated. See: http://stackoverflow.com/questions/11619680/why-should-the-observer-pattern-be-deprecated – John Smith Dec 16 '16 at 10:09
  • 1
    I agree. As long as the core state is not modified no harm done. However, I would leave it with the implementor the choice of the principle that one is willing to violate :-) – JWS Dec 16 '16 at 10:24
1

make a new sendEmail function and put the code there.

and when you need it. call it in the entire app.

Azad khan
  • 79
  • 7
1

It looks like SRP is violated

It does indeed. When you need to do multiple things you can apply the open/closed principle and decouple everything.

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); 
        } 
    } 
} 

Then you can use it like this:

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

$news->add('bla bla');
Federkun
  • 36,084
  • 8
  • 78
  • 90