Фабричный шаблон — это способ создавать объекты, не беспокоясь о том, как этот объект создается или что ему нужно, что допускает слабую связь. Это означает, что мы можем попросить наш фабричный объект предоставить нам конкретный объект, и фабрика займется его созданием. Конечно, мы должны сначала настроить нашу фабрику для создания!

Вот пример: вы хотите нанять нового разработчика для работы в вашей компании. Теперь мы можем знать, какие навыки нам нужны, но как насчет пособий по работе и проверок биографических данных? Здесь мы можем попросить менеджера по найму разобраться во всем. Менеджер по найму — это наша фабрика, поэтому мы обычно просим их: «Найдите мне разработчика с Х-навыками».

Итак, давайте создадим базовую фабрику в приложении Javascript. Наше приложение будет довольно простым; все, что он собирается сделать, это отобразить текст, установить цвет текста, а также установить цвет фона.

Наше основное приложение:

<!-- Application code -->
<html>
  <script>
    function RenderApplication() {
      const title = document.createElement("H1");
      const titleText = document.createTextNode("Basic Factory Pattern for Javascript");
      title.className = "centre";
      title.appendChild(titleText);
      document.body.appendChild(
        title
      );
    }
    window.onload = function() {
      RenderApplication();
    }
  </script>
  <style>
    .centre {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  </style>
  <body>  
  </body>
</html>

Теперь давайте создадим наш ConfigService. Это просто сохранит наш основной и дополнительный цвета, которые будут использоваться для нашего приложения, как показано ниже:

<!-- Config service -->
<script>
  function ConfigService() {
    this.Settings = [];
    this.Settings["PrimaryColour"] = '#BFFCC6';
    this.Settings["SecondaryColour"] = '#6EB5FF';
  }
</script>

И давайте продолжим и создадим наш FactoryService. Это будет связано с предоставлением нам нашего ConfigService, когда мы его попросим:

<!-- Factory Service -->
<script>
  function FactoryService() {
    this.repoList = [
      {name: 'ConfigService', source: ConfigService}
    ];
  }
  FactoryService.prototype.GetInstance = function(instanceName)
  {
    selectedRepo = this.repoList.find((element) => { return element.name == instanceName; });
    return new selectedRepo.source();
  }
  Window["FactoryService"] = new FactoryService();
</script>

Теперь, используя наши ConfigService и FactoryService, мы можем обновить наше приложение.

Мы собираемся использовать настройку основного цвета, чтобы установить цвет h1, и использовать настройку вторичного цвета, чтобы установить цвет фона тела.

Теперь мы могли бы просто создать наш ConfigService и использовать его напрямую, но тогда, если бы мы захотели заменить наш ConfigService другим ConfigService, нам пришлось бы просмотреть всю нашу кодовую базу, чтобы найти «новый ConfigService()» и заменить его.

Здесь в игру вступает наш FactoryService, поэтому давайте настроим наше приложение для использования FactoryService, когда мы хотим использовать наш ConfigService:

<!-- Full application -->
<html>
  <script>
  function ConfigService() {
    this.Settings = [];
    this.Settings["PrimaryColour"] = '#BFFCC6';
    this.Settings["SecondaryColour"] = '#6EB5FF';
  }
  </script>
  <script>
    function RepositoryFactory() {
      this.repoList = [
        {name: 'ConfigService', source: ConfigService}
      ];
    }
  RepositoryFactory.prototype.GetInstance = function(instanceName)
    {
        selectedRepo = this.repoList.find((element) => { return element.name == instanceName; });
        return new selectedRepo.source();
    }
  Window["RepositoryFactory"] = new RepositoryFactory();
  </script>
  <script>
    function RenderApplication() {
      const config = Window["RepositoryFactory"].GetInstance("ConfigService");
  const title = document.createElement("H1");
      const titleText = document.createTextNode("Basic Factory Pattern for Javascript");
      title.style.color = config.Settings["PrimaryColour"]
      title.className = "centre";
      title.appendChild(titleText);
      document.body.appendChild(
        title
      );
  document.body.style.backgroundColor = config.Settings["SecondaryColour"];
    }
  window.onload = function() {
      RenderApplication();
    }
  </script>
  <style>
    .centre {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
  </style>
<body>
</body>
</html>

Теперь наше полное приложение делает следующее: сначала мы определяем наш ConfigService (который просто содержит наши настройки). Затем мы определяем наш FactoryService, он содержит массив объектов, состоящих из имени и источника. Метод GetInstance, прикрепленный к FactoryService, используется для создания нового экземпляра, который мы запрашиваем.

Если вы посмотрите на функцию RenderApplication, то сейчас мы вызываем FactoryService, чтобы получить наш ConfigService, а затем используем массив настроек из ConfigService, чтобы установить наши цвета.

Теперь я понимаю, что мы могли бы установить цвет для нашей HTML-страницы с помощью css или любым другим способом, но я просто хотел продемонстрировать фабричный шаблон в приложении Javascript.

Также просто для бонусного раунда, скажем, мы хотели использовать другой сервис конфигурации. Благодаря шаблону factory, который мы внедрили, мы можем просто заменить этот исходный код в нашем FactorySevice следующим образом:

<!-- Random config service -->
<script>
  function RandomConfigService() {
    this.Settings = [];
    this.Settings["PrimaryColour"] = `#${Math.floor(Math.random()*16777215).toString(16)}`;
    this.Settings["SecondaryColour"] = `#${Math.floor(Math.random()*16777215).toString(16)}`;
  }
</script>
// Update our factory service to return a new RandomConfigService
<script>
  function FactoryService() {
    this.repoList = [
      {name: 'ConfigService', source: RandomConfigService}
    ];
  }
  ...
</script>

Если мы сейчас обновим наше приложение, нашему телу и тегу h1 будет назначен случайный цвет. Мы могли бы даже пойти дальше и изменить наш ConfigService, чтобы он считывал цвета из центрального бизнес-API, но это все, что касается поста.

Спасибо за прочтение, надеюсь, это помогло вам или научило вас чему-то новому. Не стесняйтесь оставлять отзывы, положительные или отрицательные!

Ссылки
Фабричный шаблон: https://www.tutorialspoint.com/design_pattern/factory_pattern.htm
Суть: https://gist.github.com/MrApproved/62f83df28cb30a41423838db3982b4a2
Обои: https://www.pexels.com/photo/business-equipment-factory-industrial-plant-357440/
Случайный шестнадцатеричный цвет: https://css-tricks.com/snippets/javascript /случайный-шестнадцатеричный-цвет/