Является ли нормальным динамическая генерация имени создаваемого класса?

Ест абстрактный супер-класс Controller, в котором заложен весь функционал, но его наследники могут использовать разные Factory или не иметь их вообще, и потому у каждого наследника должен быть описан метод getFactoryClass(), возвращающий строку с названием нужного класса (я упростил, на самом деле строка формируется на основе определённых данных, иначе можно было бы возвращать сам объект, а не его имя):

abstract class Controller
{
    public function __construct(...)
    {
        ...

        if (!empty($factory_class = $this->getFactoryClass())) {
            $this->factory = new $factory_class;
        } 
        ...
    }

    abstract protected function getFactoryClass(): string;
}

class EntryController extends Controller
{
    
    protected function getFactoryClass(): string
    {
        return '\project\EntryFactory';
    }
    
    ...
}

class MenuController extends Controller
{
    
    protected function getFactoryClass(): string
    {
        return ''; // Factory не требуется
    }
    
    ...
}


Всё работает прекрасно, однако PHPStorm, например, перестаёт определять, что в свойстве $this->factory лежит объект Factory и каждый раз при использовании методов объекта пишет, что у него таких методов нет:
8fc6b31e4f0642d0a68cfa7626bf035a.png

Вопрос: это заморочка PHPStorm, на которую не стоит обращать внимания, или же это плохая практика - создание классов на основе динамически формируемых строк с именем?
Просто динамическое формирование имён позволяет значительно сократить количество кода в наследниках, но я не знаю, насколько это допускается.
  • Вопрос задан
  • 169 просмотров
Решения вопроса 1
usdglander
@usdglander Куратор тега PHP
Yipee-ki-yay
Вполне нормальная практика, если я правильно понял вопрос. Во многих фреймворках такой подход используется. Без этого никуда.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
miraage
@miraage
Старый прогер
В таком случае, FactoryClass должен реализовывать какой-то интерфейс.
Просто напишите такое:

/**
 * @var SomeInterface
 */
protected $factory;
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы