Как правильно реализовать фабрику
Парни. Есть дилемма
class Provider {
$classes = [
One::class,
//...
Last::class,
];
public function __construct(ContainerInterface $container)
public function register() {
$app->bind(Factory::class);
$app->resolving(Factory::class, function(Factory $factory) {
foreach ($classes as $class) {
$factory->add($container->get($class));
}
});
}
}
class Controller {
public function __construct(Factory $factory);
public function action() {
$service = $factory->create(/** arguments */);
$result = $service->handle(/** arguments */);
}
}
class Factory {
$instances = [];
public function add(SomeInterface $instance) {
$instances[] = $instance;
}
public function create(/** arguments */) {
foreach ($instances as $instance) {
if ($instance->check(/** arguments */)) {
return $instance;
}
}
throw Exception('Undefined type');
}
}
interface SomeInterface {
public function check(/** arguments */): bool;
public function handle(/** arguments */): void;
}
class One implements SomeInterface {
public function __construct(/** dependencies */)
public function check(/** arguments */): bool;
public function handle(/** arguments */): void;
}
// ...
class Last implements SomeInterface {
public function __construct(/** dependencies */)
public function check(/** arguments */): bool;
public function handle(/** arguments */): void;
}
По сути есть однотипная логика, которую инкапсулируем в классы вместе со знаниями, в каких случаях эта логика должна выполняться. В провайдере мы инстанцируем все сервисы и запихиваем в Factory которая вернет нужный сервис Размещать логику выбора того или иного сервиса в Factory не хочется, потому размещаем в самом сервисе. При этом каждый сервис может иметь свои зависимости пробросом через DI.
При всем этом очевидна проблема с инстанцированием всех объектов со всеми их зависимостями. Как бы это сделать по правильному, чтоб не инстанцировать все объекты на стадии провайдера?