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
244 +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 Апр 2024 в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир