Javascript. Builder pattern

Паттерн Строитель (Builder pattern) инкапсулирует конструирование продукта и позволяет разделить его на этапы, тем самым инкапсулируется процесс создания сложного объекта. Данный паттерн относится к порождающим паттернам, дает возможность поэтапного конструирования объекта с переменным набором этапов (в отличие от "одноэтапных" фабрик). Также данный паттерн скрывает внутреннее представление продукта от клиента. Часто используется для создания составных структур. Ниже приводится пример реализации паттерна.


/* Director */

function Shop() {
    this.construct = function(builder) {
        builder.step1();
        builder.step2();
        return builder.get();
    }
}

/* ConcreteBuilder */

function CarBuilder() {
    this.car = null;

    this.step1 = function() {
        this.car = new Car();
    };

    this.step2 = function() {
        this.car.addParts();
    };

    this.get = function() {
        return this.car;
    };
}

/* ConcreteBuilder */

function TruckBuilder() {
    this.truck = null;

    this.step1 = function() {
        this.truck = new Truck();
    };

    this.step2 = function() {
        this.truck.addParts();
    };

    this.get = function() {
        return this.truck;
    };
}

/* Product */

function Car() {
    this.doors = 0;

    this.addParts = function() {
        this.doors = 4;
    };

    this.say = function() {
        log.add("I am a " + this.doors + "-door car");
    };
}

/* Product */

function Truck() {
    this.doors = 0;

    this.addParts = function() {
        this.doors = 2;
    };

    this.say = function() {
        log.add("I am a " + this.doors + "-door truck");
    };
}

// log helper
var log = (function () {
    var log = "";
    return {
        add: function (msg) { log += msg + "\n"; },
        show: function () { console.log(log); log = ""; }
    }
})();

// testing...

var Application = function () {
this.run = function () {
var shop = new Shop(),
carBuilder = new CarBuilder(),
truckBuilder = new TruckBuilder(),
car = shop.construct(carBuilder),
truck = shop.construct(truckBuilder);
 
car.say();
truck.say();
 
log.show();
};
};

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

На выходе имеем:

I am a 4-door car
I am a 2-door truck

Всем удачи в нашем нелегком пути :)