Decorator реализующий интерфейс, а не конкретный класс, возможно ли? Помогите разрулить зависимости. Итак, допустим у нас есть некий интерфейс Repository:interface Repository
{
public function create();
public function update();
public function save();
}
Есть абстрактный класс реализующий этот интерфейс:abstract class UsersRepository implements Repository
{
...
}
И есть конкретный репозиторий, работающий с БДclass DBUsersRepository extends UsersRepository
{
...
}
Причем реализация написана таким образом, что ф-ии creatе() и update() связаны с save() - она общая.
Дальше в приложении появляется логика валидации, внедрение которой как раз и хочется сделать через Декоратор. В случае если класс Декоратора наследовать от DBUsersRepository - проблем никак нет. Но этот Декоратор должен быть общим для всех репозиториев независимо от конкретной реализации:class ValidationRepository implements Repository
{
protected $repository;
protected $validator;
public function __construct(Repository $repository)
{
$this->repository = $repository;
}
public function setValidator(Validator $validator)
{
$this->validator = $validator;
return $this;
}
public function save($model)
{
if($this->validator->validate($model)){
return $this->repository->save($model);
}
}
}
Как видно декоратор расширяет только один метод интерфейса. Отсюда вопрос, что делать с остальными? Они должны быть и работать должны аналогично принимаемого $repository, но в собственном контексте. Чтобы клиентский код:$rep = new ValidationRepository( new DBUsersRepository());
$rep->setValidator($validator);
$rep->create($modelsData); //create() должен вызваться из UsersRepository, а функция save() в нем - уже из ValidationRepository
Отрабатывал корректно.

21 Авг 2019 в 07:06
227 +1
0
Ответы
1

Для того чтобы декоратор работал корректно и для остальных методов интерфейса Repository, необходимо в классе ValidationRepository также реализовать эти методы, которые необходимо расширить или оставить без изменений.

Примерно таким образом можно реализовать декоратор для остальных методов интерфейса Repository:

class ValidationRepository implements Repository
{
protected $repository;
protected $validator;
public function __construct(Repository $repository)
{
$this->repository = $repository;
}
public function setValidator(Validator $validator)
{
$this->validator = $validator;
return $this;
}
public function create($model)
{
return $this->repository->create($model);
}
public function update($model)
{
return $this->repository->update($model);
}
public function save($model)
{
if($this->validator->validate($model)){
return $this->repository->save($model);
}
}
}

Таким образом, в декораторе ValidationRepository реализованы все методы интерфейса Repository, для которых необходимо использовать дополнительную логику валидации. Клиентский код, использующий данный декоратор, будет также работать корректно с остальными методами интерфейса Repository.

20 Апр в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 92 493 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир