Шаблон наблюдателя или вспомогательный класс? (РНР)

1

давайте представим нашу систему форума, я хочу оставить комментарий

class Thread
{
    public function post ($userId, $threadId, $comment)
    {
        SQL INSERT INTO table $userId, $threadId, $comment
        // sending emails
        // public on a notice-wall
    }
}

Я не хочу, чтобы хард public on a notice-wall код sending emails и public on a notice-wall кодах public on a notice-wall, потому что даже это было бы всего два вызова метода, это повредит принципу SRP. Я вижу два пути:

используя помощник:

public function post ($userId, $threadId, $comment)
{
    SQL INSERT INTO table $userId, $threadId, $comment
    ForumHelper::sendEmailsAndPublicOnNoticeWall ($userId, $threadId, $comment);
}

но они говорят, что это признак плохой практики. Во-вторых, я мог бы использовать Pattern наблюдателя. Что использовать тогда?

  • 1
    Вы уже нарушаете SRP в своем псевдокоде, привязывая его к специфичным для хранилища материалам (то есть к SQL). Что если память изменится? Или если его версия / формат меняется? Это должно быть работа для слоя модели картографов данных. Что касается вопроса - используйте цепочку обработки, где вы будете регистрировать любые действия, необходимые для выполнения ваших методов. Затем вы сможете настроить его и изолировать логику сущности от логики обработки событий +, избегая неочевидных «запускающих» вещей (представьте - если у вас есть 10+ событий в «наблюдениях»), насколько болезненным будет получить то, что происходит в этой магии)
Теги:
observer-pattern

1 ответ

1
Лучший ответ

class Thread
{
    // ideally make this protected and use setters / getters,
    // you could also consider to use an array of listeners
    // to have multiple listeners
    public $listener = NULL; 

    public function postComment($userId, $threadId, $comment)
    {
        // SQL INSERT INTO table $userId, $threadId, $comment
        // let assume that you have a $post object with the
        // informations regarding your post

        $this->_notifyOfCommentPost($postedComment);
    }

    protected function _notifyOfCommentPost($postedComment) {
        if (!isset($this->listener)) {
            return;
        }
        $this->listener->onPostCommented($postedComment);
    }
}

Эта структура позволяет вам определить слушателя:


class OnCommentPostedListener {
    public function onCommentPosted($postedComment) {
        ForumHelper::sendEmailsForComment($postedComment);
        ForumHelper::sendPublicOnNoticeWallForComment($postedComment);
    }
}

$thread->listener = new OnCommentPostedListener();

Здесь поведение, связанное с тем, что делать, когда отправлено комментарий, не входит в класс Thread, управляющий вашим потоком. Ваша модель (как вы храните информацию) не знает о вашей бизнес-логике (отправка сообщений электронной почты и уведомлений о проводке), она просто уведомляет внешний мир (наблюдаемый шаблон), когда он выполняет операцию.

Преимущество этого заключается в том, что добавление нового поведения после публикации нового комментария не требует изменения вашего класса Thread.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню