наш блог

Шаблон проектирования Factory Method в реализации на JavaScript

Продолжаем серию статей о паттернах. В этот раз рассмотрим шаблон проектирования Factory Method – или фабричный метод – в реализации на JavaScript.

Как гласит «Википедия», фабричный метод – это порождающий шаблон проектирования, который предоставляет дочерним классам интерфейс для создания экземпляров некоторого класса. Впрочем, так как в JavaScript отсутствует понятие «интерфейс», то и алгоритм реализации в этом языке будет отличаться от набора манипуляций, необходимых в случае работы с Java или C#.

Начнем. Напишем класс фабрики. Допустим, это будет фабрика транспорта:

class TransportFactory {
 static createTransport(type) {
   switch(type) {
     case 'Moto':
       return new Moto;
     case 'Car':
       return new Car;
   }
 }
}

В фабрике укажем статический метод createTransport(), который в зависимости от переданного параметра будет создавать и возвращать экземпляры класса автомобиль или мотоцикл. Ниже определим эти классы:

class Car {
 constructor() {
   this.color = 'white';
   this.maxSpeed = 300;
   this.wheels = 4
 }
}
class Moto {
 constructor() {
   this.color = 'black';
   this.maxSpeed = 200;
   this.wheels = 2
 }
}

В конструкторе классов просто-напросто инициализируем их свойства. И проверим как все работает.

class TransportFactory {
 static createTransport(type) {
   switch(type) {
     case 'Moto':
       return new Moto;
     case 'Car':
       return new Car;
   }
 }
}

class Car {
 constructor() {
   this.color = 'white';
   this.maxSpeed = 300;
   this.wheels = 4
 }
}

class Moto {
 constructor() {
   this.color = 'black';
   this.maxSpeed = 200;
   this.wheels = 2
 }
}

const moto = TransportFactory.createTransport('Moto');
const car = TransportFactory.createTransport('Car');

console.log(moto); // Moto { color: 'black', maxSpeed: 200, wheels: 2 }
console.log(car); // Car { color: 'white', maxSpeed: 300, wheels: 4 }

Обратимся к классу TransportFactory. Вызовем в нем статический метод createTransport, в который и передадим строку с названием типа целевого класса.

К слову, существует еще один способ реализации фабричного метода. Он не требует конструирования перебора:

const types = {
 Moto,
 Car
};

class TransportFactory {
 static createTransport(type) {
   return new types[type]
 }
}

Записываем список классов в объект types. Переписываем статический метод класса createTransport так, чтобы он обращался к объекту types и находил поле с именем нужного класса, который приходит в аргументы метода createTransport, возвращая его экземпляр.

class Car {
 constructor() {
   this.color = 'white';
   this.maxSpeed = 300;
   this.wheels = 4
 }
}

class Moto {
 constructor() {
   this.color = 'black';
   this.maxSpeed = 200;
   this.wheels = 2
 }
}

const types = {
 Moto,
 Car
};
class TransportFactory {
 static createTransport(type) {
   return new types[type]
 }
}

const moto = TransportFactory.createTransport('Moto');
const car = TransportFactory.createTransport('Car');

console.log(moto); // Moto { color: 'black', maxSpeed: 200, wheels: 2 }
console.log(car); // Car { color: 'white', maxSpeed: 300, wheels: 4 }

Юрий Кизилов, компания Craft Group