Builder pattern

by Artem

JavaScript

'use strict';

const Car = (function() {
  function Car() {}
  Car.prototype.createBody = function() {};

  return Car;
}());

const Builder = (function() {
  const product = Symbol('product');

  function Builder() {
    if (this instanceof Builder) {
      throw new TypeError(`Can't instantiate abstract constructor`);
    }
    Reflect.defineProperty(this, 'product', {
      get() {
        return this[product];
      }
    });
  }

  Builder.prototype.init = function() {
    throw new TypeError('Unimplemented abstract method - init');
  };
  Builder.prototype.buildBody = function() {
    throw new TypeError('Unimplemented abstract method - buildBody');
  };
  Builder.prototype.buildWheels = function() {
    throw new TypeError('Unimplemented abstract method - buildWheels');
  };
  Builder.prototype.buildEngine = function() {
    throw new TypeError('Unimplemented abstract method - buildEngine');
  };
  Builder.prototype.buildSuspension = function() {
    throw new TypeError('Unimplemented abstract method - buildSuspension');
  };
  Builder.prototype.paint = function() {
    throw new TypeError('Unimplemented abstract method - paint');
  };

  return Builder;
}());

const CarBuilder = (function(Builder) {
  const product = Symbol('product');

  function CarBuilder() {
    Reflect.defineProperty(this, 'product', {
      get() {
        return this[product];
      }
    });
  }
  CarBuilder.prototype = Object.create(Builder.prototype);
  CarBuilder.prototype.constructor = CarBuilder;

  CarBuilder.prototype.init = function() {
    this[product] = new Car();
  };
  CarBuilder.prototype.buildBody = function() {
    this[product].createBody();
  };

  return CarBuilder;
}(Builder));

const Department = (function() {
  function Department() {}
  Department.prototype.construct = function(builder) {
    builder.init();
    builder.buildBody();
    return builder.product;
  };

  return Department;
}());

const department = new Department();
const carBuilder = new...