Я не нашел сообщение в блоге, на которое вы ссылались, очень интересным или проницательным.
То, что вы описываете, больше похоже на Decorator , чем что-либо связанное с внедрением зависимостей. Внедрение зависимостей - это способ построения графиков объектов, а не их состояние после создания.
Тем не менее, я бы предложил взять ваш шаблон Decorator и работать с ним.
interface PostInterface
{
public function title();
}
class PostModel implements PostInterface
{
public function title()
{
return $this->title;
}
}
class PostViewHelper implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->post = $post;
}
public function title()
{
return $this->post->title();
}
}
class PostFilter implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->post = $post;
}
public function title()
{
return $this->filter($this->post->title());
}
protected function filter($str)
{
return "FILTERED:$str";
}
}
Вы бы просто использовали любую DI-инфраструктуру для построения этого графа объектов следующим образом:
$post = new PostFilter(new PostViewHelper($model)));
Я часто использую этот подход при построении сложных вложенных объектов.
Одна из проблем, с которой вы можете столкнуться - это определение «слишком большого количества» функций в вашем PostInterface
. Это может быть боль , чтобы реализовать их в каждом классе декоратора. Я использую магические функции PHP, чтобы обойти это.
interface PostInterface
{
/**
* Minimal interface. This is the accessor
* for the unique ID of this Post.
*/
public function getId();
}
class SomeDecoratedPost implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->_post = $post;
}
public function getId()
{
return $this->_post->getId();
}
/**
* The following magic functions proxy all
* calls back to the decorated Post
*/
public function __call($name, $arguments)
{
return call_user_func_array(array($this->_post, $name), $arguments);
}
public function __get($name)
{
return $this->_post->get($name);
}
public function __set($name, $value)
{
$this->_post->__set($name, $value);
}
public function __isset($name)
{
return $this->_post->__isset($name);
}
public function __unset($name)
{
$this->_post->__unset($name);
}
}
Используя этот тип декоратора, я могу выборочно переопределить любой метод, который мне нужен для обеспечения декорированной функциональности. Все, что я не перезаписываю, передается обратно в базовый объект. Множество украшений может происходить при сохранении интерфейса нижележащего объекта.