Какой шаблон проектирования тут можно использовать?

Уже не первый раз попадается задача на работе, как та, что опишу ниже и я не знаю какой паттерн можно применить корректно. Может быть подскажите.

Условно так: в GET параметре прилетает тип (type) фигуры, которую нужно отрисовать. Неважно какая длина, ширина, диаметр и пр. Любой. Просто нужно отрисовать фигуру по типу. Их ограниченное количество. Я делаю так:

  • Делаю абстрактный класс Figure, где есть protected static $type = '' и абстрактный метод render

  • Делаю несколько фигур, наследников от Figure , в которых переопределяю как свойство, так и метод. Получается что-то типа SquareFigure extends Figure, CircleFigure extends Figure, TriangleFigure extends Figure и т.д.

  • А дальше, т.к. заранее тип неизместен, делаю FigureManager в котором есть мапа, из которой можно достать наименование класса по его типу:

      class FigureManager {
    
          public static function getFiguresMap() {
              return [
                  SquareFigure::getType() => SquareFigure::class,
                  CircleFigure::getType() => CircleFigure::class,
                  TriangleFigure::getType() => TriangleFigure::class
              ];
          }
      }
    
  • Теперь в нужно месте я пишу что-то типа такого:

      $figureType = $_GET['type'];
    
      $figureClassName = FigureManager::getFiguresMap()[$figureType];
      $figure = new $figureClassName();
      $figure->render();
    

Всё хорошо, но проблема в том, что есть какой-то класс, который знает о всех типах фигур. Хранит в себе мапу. И при добавлении новой, нужно добавлять туда ещё одну. Если фигур будет 4-5 - не страшно, а если 40-50? В общем, нормально ли делать так, я делаю? То есть выбора в данном случае нет? Или есть более практичный способ сделать это по феншую? Применить корректно какой-либо паттерн проектирования. Подскажите, пожалуйста.


Ответы (1 шт):

Автор решения: Alex Khonko

У вас прикладная задача

В общем, нормально ли делать так

В общем да, почему нет, если у вас только 1 класс будет работать с этим перечнем, то ок.

Если много, то это уже фи. Вы сами со временем загнетесь добавлять везде, и вспомните про O из солида


Ваш код можно немножко улучшить, если переписать под фабрику:

  $figureType = $_GET['type'];

  $figure = FigureFactory::getFigure(figureType);
  $figure->render();


+, так же в вопросе вы это не указали, от себя добавлю, что тип фигуры было бы круто загнать в Enum, типа https://github.com/myclabs/php-enum

  $figureType = FigureType::from($_GET['type']);

  $figure = FigureFactory::getFigure(figureType);
  $figure->render();

→ Ссылка