Мне интересно, есть ли какая-то лучшая практика для следующего случая.
Например, у меня есть несколько служб, и я внедряю их все в виде массива в службу "фабрики".Тогда я вызываю метод этой фабрики и хочу получить только одну услугу в зависимости от некоторых условий.После этого я запускаю эту службу и получаю результат ...
Однако для некоторых из этих служб требуется случайная строка, которую я получаю из запроса клиента.
Конечно, я могу вызватьМетод сервиса с этой строкой в качестве параметра, но некоторые сервисы не требуют этой строки, и я получу «неиспользуемую переменную» в методе.
Я думаю, что я мог бы получить сервис с фабрики и затем вызвать сеттердобавить эту строку в сервис.Но это не похоже на службу без сохранения состояния.
Есть ли более элегантное решение для передачи параметров, которые я не мог бы ввести в службу или использовать для этого установщик?
Вот как это выглядит вмой код
Во-первых, у меня есть интерфейс всех серверов, которые я хочу проверить.Служба должна поддерживать клиента, а затем предоставлять информацию из DTO.
interface Renderable {
public function supports(Customer $customer);
public function render(CustomerDTO $dto);
}
Далее у меня есть несколько служб.Этот использует DTO для визуализации данных.
class ServiceOne implements Renderable
{
public function suppots(Customer $customer)
{
return $customer->getPriority() === 1;
}
public function render(CustomerDTO $dto)
{
return 'One: '.$dto->getName();
}
}
Однако некоторые сервисы не нуждаются в DTO для визуализации, они просто предоставляют жестко закодированное значение.
class ServiceTwo implements Renderable
{
public function suppots(Customer $customer)
{
return $customer->getPriority() !== 1;
}
// service does not use DTO, it simply output result
// so, I'll get a notice about unused variable
// and I can not remove it from the method since it is in interface
public function render(CustomerDTO $dto)
{
return 'Two';
}
}
Это фабрика.Все сервисы внедрены в виде массива.Затем он проверяет и возвращает первый сервис, который поддерживает экземпляр клиента.
class ServiceFactory
{
/** @var Renderable[] */
private $services;
public function __construct(iterable $services)
{
$this->services = $services;
}
public function getRenderer(Customer $customer)
{
foreach ($this->services as $service)
{
if ($service->supports($customer)
{
return $service;
}
}
}
}
Здесь я использую фабрику и ее результат
$customer = ...; // it comes from a database
$request = ...; // it comes from a http request
$renderService = $factory->getRenderer($customer);
$customerDTO = CustomerDTO::createFromData([
'customerUid' => $customer->getUid(),
'date' => new \DateTime(),
'name' => $request->getSheetUid(),
'tags' => $request->getTags(),
]);
$renderService->render($customerDTO);
Итак, мне нужно вызвать Renderer :: renderс экземпляром DTO.Но некоторые сервисы не используют его для «рендеринга» данных.Я также не могу внедрить его в службу рендеринга, поскольку этот объект (DTO) создается во время выполнения, когда все службы уже внедрены.Я также не могу ввести RequestStack в сервис.