Abstract factory
by Artem
JavaScript
'use strict';
const __extends__ = (Parent, Child) => {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.super = Parent;
};
const __getRandomId__ = () => Math.random().toString(36).slice(2);
const __makeConstructor__ = (factoryName, type) => {
return function(id) {
Reflect.defineProperty(this, type, {
get() {
return {
id,
type: `${factoryName} ${type}`
};
},
set(newValue) {
throw new TypeError(`Can't redefine ${type}`);
}
});
};
};
const CarEngine = __makeConstructor__('Car', 'engine');
const CarSuspension = __makeConstructor__('Car', 'suspension');
const MotocycleEngine = __makeConstructor__('Motocycle', 'engine');
const MotocycleSuspension = __makeConstructor__('Motocycle', 'suspension');
const AbstractFactory = (function() {
function AbstractFactory(brand) {
if (this instanceof AbstractFactory) {
throw new TypeError('Can\'t instantiate abstract constructor');
}
}
AbstractFactory.prototype.createEngine = function(id) {
throw TypeError('Unimplemented abstract method - createEngine');
}
AbstractFactory.prototype.createSuspension = function(id) {
throw TypeError('Unimplemented abstract method - createSuspension');
}
return AbstractFactory;
}());
const CarFactory = (function(ParentFactory) {
function CarFactory(brand) {
Reflect.defineProperty(this, 'brand', {
get() {
return brand;
},
set(newBrand) {
throw new TypeError('Can\'t redefine brand');
}
})
}
__extends__(ParentFactory, CarFactory);
CarFactory.prototype.createEngine = function(id = __getRandomId__()) {
return new CarEngine(id);
};
CarFactory.prototype.createSuspension = function(id = __getRandomId__()) {
return new CarSuspension(id);
};
return CarFactory;
}(AbstractFactory));
const MotocycleFactory = (function(ParentFactory) {
...