давайте представим нашу систему форума, я хочу оставить комментарий
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 наблюдателя. Что использовать тогда?
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.