Class ValidatorComponent
{
const ERR_BAD_PATH = 1;
const ERR_BAD_ARGUMENT = 2;
private $path;
public function __construct(PathComponent $path)
{
$this->path = $path;
}
public function someMethod()
{
return true;
}
public function isPath($path) : int
{
return $this->path->isPath($path) ? 0 : self::ERR_BAD_PATH;
}
public function isCorrectArgument($argument)
{
return $this->someMethod($argument) ? 0 : self::ERR_BAD_ARGUMENT;
}
}
Class PathComponent
{
private $validator;
public function __construct(ValidatorComponent $validator)
{
$this->validator = $validator;
}
public function isPath($path)
{
return true;
}
public function someAction($argument)
{
if (! $this->validator->isCorrectArgument($argument)) throw new InvalidArgumentException($argument);
// do something
}
}
Получается что модули взаимозависимы.
Большинство фреймворков решает это иньекцией зависимостей, на деле просто в момент когда нужно получить модуль-исполнитель обращаются в контейнер и берут его оттуда
Происходит "отложенное создание обьекта", которое можно объявить
- колбэком (в конфиге инжектора) - сначала создаем первый, кидаем в него второй ещё не готовый, потом допиливаем первый, а поскольку по ссылке - то будет работать
- методом (зашить контейнер прямо в модуль и запросить явно $this->container->get())
- фабрикой (кинуть на вход фабрику которая в нужный момент выполнит обращение в контейнер $this->factory->create() а под капотом все равно $this->container->get())
и т.д.
Какой-нибудь грамотный способ перепроектирования такой связи классов есть, чтобы динамически обращаться в контейнер не приходилось?
ps. есть глупая догадка типа я попытался объединить в одном модуле "опрос системы" и "изменение системы", дескать нужно ввести класс который будет делать someAction() и ему нужен валидатор, и класс который содержит проверки - которому требуется модуль, вместо того чтобы избавиться от циклической зависимости 1 к 1, ввести третьего и тогда зависимость будет не взаимная