Я пытаюсь спроектировать базу для создания сервиса по работе с виджетами. Все виджеты зависят от обьекта Client и шаблонизатора TemplateService.
Выделив общие свойства и методы получилась такая структура:
Родительский класс Widget:abstract class Widget
{
protected $client;
protected $templateService;
protected $template;
public function __construct(TemplateService $templateService, Client $client)
{
$this->templateService = $templateService;
$this->client = $client;
}
public function setTemplate(string $template)
{
if (!file_exists($template)) {
throw new \Exception('Widget template "' . $template . '" was not found.');
}
$this->template = $template;
return $this;
}
abstract protected function renderWidget() : string;
}
Пример потомка ContactWidget:class ContactWidget extends Widget implements ICustomerForm
{
use CustomerFormTrait;
private $formFactory;
public function __construct(TemplateService $templateService, $client, FormFactoryInterface $form)
{
parent::__construct($templateService, $client);
$this->formFactory = $form;
}
public function renderWidget() : string
{
$form = $this->buildForm();
return $this->templateService->render($this->template, [
'form' => $form->createView(),
'token' => $this->client->getToken()
]);
}
public function buildForm() : FormInterface
{
$form = $this->formFactory->create(ContactType::class, $this->customer);
return $form;
}
}
Пример потомка TestimonialWidget:class TestimonialWidget extends Widget
{
public function __construct(TemplateService $templateService, Client $client)
{
parent::__construct($templateService, $client);
}
public function renderWidget() : string
{
$testimonials = $this->client->getTestimonials();
return $this->templateService->render($this->template, [
'testimonials' => $testimonials
]);
}
}
Все работает, но решение кажется не очень красивым. Придерживаясь этой структуры придется каждый раз вызывать родительский конструктор. Мне кажется существует решение поизящнее и хочется изначально заложить правильную структуру. Отказаться от конструктора в родительском классе или в классе потомка? Передавать зависимости через set/get?
Что нужно изменить или какой паттерн можно применить в данном случае?