Javascript. Factory Method pattern

Паттерн Фабричный Метод (Factory Method) определяет интерфейс создания объекта, но позволяет субклассам выбрать класс создаваемого экземпляра. Таким образом, Фабричный метод делегирует операцию создания экземпляра субклассам. Относится к порождающим шаблонам проектирования.



Паттерн Фабричный Метод, как все остальные разновидности фабрик, предоставляет интерфейс к методу создания объектов, также называемому "фабричным методом". Остальные методы, реализуемые в абстрактном классе Creator, работают с продуктами, созданными фабричным методом. Только субклассы фактически реализуют фабричный метод и создают продукты.
Рассмотрим паттерн на примере заказа пиццы с использованием фабричного метода.

/* Product - Pizza */

var Pizza = function () {

    this.prepare = function () {
        console.log("Preparing " + this.name);
        console.log("Tossing dough...");
        console.log("Adding sauce...");
        console.log("Adding toppings: ");
        for (var i = 0; i < this.toppings.length; i++) {
            console.log("  " + this.toppings[i]);
        }
    };
   
    this.bake = function () {
        console.log("Bake for 25 minutes at 350");
    };
   
    this.cut = function () {
        console.log("Cutting the pizza into diagonal slices");
    };
   
    this.box = function () {
        console.log("Place pizza in official PizzaStore box");
    };
   
    this.getName = function () {
        return this.name;
    };

};

/* ConcreteProduct - NYStyleCheesePizza */

var NYStyleCheesePizza = function () {
    this.name = "NY Style Sauce and Cheese Pizza";
    this.dough = "Thin Crust Dough";
    this.sauce = "Marinara Sauce";
    this.toppings = ["Grated Reggiano Cheese"];
};

NYStyleCheesePizza.prototype = new Pizza();
NYStyleCheesePizza.prototype.constructor = NYStyleCheesePizza;

/* ConcreteProduct - ChicagoStyleCheesePizza */

var ChicagoStyleCheesePizza = function () {
    this.name = "Chicago Style Deep Dish Cheese Pizza";
    this.dough = "Extra Thick Crust Dough";
    this.sauce = "Plum Tomato Sauce";
    this.toppings = ["Shredded Mozzarella Cheese"];
    this.cut = function () {
        console.log("Cutting the pizza into square slices");
    };
};

ChicagoStyleCheesePizza.prototype = new Pizza();
ChicagoStyleCheesePizza.prototype.constructor = ChicagoStyleCheesePizza;

/* Creator - PizzaStore */

var PizzaStore = function () {

    this.orderPizza = function () {
        var pizza = this.createPizza();
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza
    };

    // abstract createPizza();

};

/* ConcreteCreator - NYPizzaStore */

var NYPizzaStore = function () {
    // factory method
    this.createPizza = function () {
        return new NYStyleCheesePizza();
    };
};

NYPizzaStore.prototype = new PizzaStore();
NYPizzaStore.prototype.constructor = NYPizzaStore;

/* ConcreteCreator - NYPizzaStore */

var ChicagoPizzaStore = function () {
    // factory method
    this.createPizza = function () {
        return new ChicagoStyleCheesePizza();
    };
};

ChicagoPizzaStore.prototype = new PizzaStore();
ChicagoPizzaStore.prototype.constructor = ChicagoPizzaStore;

/* test application */

var Application = function () {
    this.run = function () {
       
        var nyStore = new NYPizzaStore();
        var chicagoStore = new ChicagoPizzaStore();
       
        var pizza = nyStore.orderPizza();
        console.log("Ethan ordered a " + pizza.getName());
       
        pizza = chicagoStore.orderPizza();
        console.log("Joel ordered a " + pizza.getName());
       
    };
};

var application = new Application();
application.run();


На выходе:

Preparing NY Style Sauce and Cheese Pizza
Tossing dough...
Adding sauce...
Adding toppings:
  Grated Reggiano Cheese
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a NY Style Sauce and Cheese Pizza

Preparing Chicago Style Deep Dish Cheese Pizza
Tossing dough...
Adding sauce...
Adding toppings:
  Shredded Mozzarella Cheese
Bake for 25 minutes at 350
Cutting the pizza into square slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Deep Dish Cheese Pizza