Patrón creacional Abstract Factory(JavaScript) - fapaccha/Dise-o-dirigido-por-el-modelo GitHub Wiki
Abstract Factory(JavaScript)
Este patrón se le considera como super-factory, ya que de manera interna tiene dos o más Factory Method Primero generamos la clase principal Vehicle, donde va a tener sus propiedades y métodos:
Podemos observar que tenemos una clase principal Vehicle y que tenemos 8 subclases (4 para carros, 4 para motos), para llegar al patrón de Abstract Factory, primero debemos usar el Factory Method:
class Vehicle {
constructor(type, model) {
this._model = model;
this._type = type;
}
get model(){
return this._model;
}
get type(){
return this._type;
}
description(){
return `I am of type "${this.type}" and my model is "${this.model}!"`
}
}
export default Vehicle;
Lo que hacemos es crear un Factory para cada uno de los tipos MotorcycleFactory y CarFactory, donde cada uno de ellos va a hacer la instancia del objeto dependiendo de las propiedades que se le pasen; hasta aquí hemos cumplido con el patrón de Factory Method, ahora lo que vamos a hacer es crear un super-factory FactoryProvider, para que esté a su vez mande a llamar los factory MotorcycleFactory, CarFactory.
import Vehicle from "./Vehicle";
class MotorcycleType1 extends Vehicle {
constructor() {
super("motorcycle", "deportiva");
}
}
class MotorcycleType2 extends Vehicle {
constructor() {
super("motorcycle", "motoneta");
}
}
class MotorcycleType3 extends Vehicle {
constructor() {
super("motorcycle", "moto");
}
}
class MotorcycleType4 extends Vehicle {
constructor() {
super("motorcycle", "cuatrimoto");
}
}
export { MotorcycleType1, MotorcycleType2, MotorcycleType3, MotorcycleType4 };
import Vehicle from "./Vehicle";
class CarType1 extends Vehicle {
constructor() {
super("car", "super");
}
}
class CarType2 extends Vehicle {
constructor() {
super("car", "deportivo");
}
}
class CarType3 extends Vehicle {
constructor() {
super("car", "combi");
}
}
class CarType4 extends Vehicle {
constructor() {
super("car", "clasico");
}
}
export { CarType1, CarType2, CarType3, CarType4 };
Generamos dos clases Factory MotorcycleFactory y CarFactory, donde dependiendo del modelo model que se la mande es la instancia de objeto que va a realizar:
import {
MotorcycleType1,
MotorcycleType2,
MotorcycleType3,
MotorcycleType4
} from "./Motorcycle";
class MotorcycleFactory {
create(model) {
switch (model) {
case "deportiva":
return new MotorcycleType1();
case "motoneta":
return new MotorcycleType2();
case "moto":
return new MotorcycleType3();
case "cuatrimoto":
return new MotorcycleType4();
default:
console.log("Model not found ", model);
break;
}
}
}
export default MotorcycleFactory;
import { CarType1, CarType2, CarType3, CarType4 } from "./Car";
class CarFactory {
create(model) {
switch (model) {
case "super":
return new CarType1();
case "deportivo":
return new CarType2();
case "combi":
return new CarType3();
case "clasico":
return new CarType4();
default:
console.log("Model not found ", model);
break;
}
}
}
export default CarFactory;
Y por último creamos el super-factory que es la clase FactoryProvider, donde va a mandar a llamar a las clases Factory, dependiendo del tipo type que se le mande:
import CarFactory from "./CarFactory";
import MotorcycleFactory from "./MotorcycleFactory";
class FactoryProvider {
createType(type) {
if (type === "car") {
return new CarFactory();
} else if (type === "motorcycle") {
return new MotorcycleFactory();
} else {
console.log("Error type");
}
}
}
export default FactoryProvider;