Comparto mi solución n.n
type AvailableColors =
| "red"
| "black"
| "gray"
| "blue"
| "sky blue"
| "white"
| "default";
// STEP 1
interface CarProductionLine {
setAirBags(howMany: number): CarProductionLine;
setColor(color: AvailableColors): CarProductionLine;
setEdition(edition: EditionsType): CarProductionLine;
resetProductionLine(): void;
}
// STEP 2
type CarCatalog = "mastodon" | "rhino";
type ConstructorParams = { modelToCustomizeInLine: CarCatalog };
type EditionsType = "cvt" | "signature" | "sport" | "default";
class SedanProductionLine implements CarProductionLine {
private sedanCar!: BaseCar;
private modelToCustomizeInLine!: CarCatalog;
constructor({ modelToCustomizeInLine }: ConstructorParams) {
this.setModelToBuild(modelToCustomizeInLine);
this.resetProductionLine();
}
setAirBags(howMany: number): SedanProductionLine {
this.sedanCar.airBags = howMany;
return this;
}
setColor(color: AvailableColors): SedanProductionLine {
this.sedanCar.color = color;
return this;
}
setEdition(edition: EditionsType): SedanProductionLine {
this.sedanCar.edition = edition;
return this;
}
setModelToBuild(model: CarCatalog) {
this.modelToCustomizeInLine = model;
}
resetProductionLine() {
this.sedanCar =
this.modelToCustomizeInLine === "mastodon"
? new MastodonSedanCar()
: new RhinoSedanCar();
}
build(): BaseCar {
const sedanCar = this.sedanCar;
this.resetProductionLine();
return sedanCar;
}
}
class HatchBackProductionLine implements CarProductionLine {
private hatchbackCar!: BaseCar;
private modelToCustomizeInLine!: CarCatalog;
constructor({ modelToCustomizeInLine }: ConstructorParams) {
this.setModelToBuild(modelToCustomizeInLine);
this.resetProductionLine();
}
setAirBags(howMany: number): HatchBackProductionLine {
this.hatchbackCar.airBags = howMany;
return this;
}
setColor(color: AvailableColors): HatchBackProductionLine {
this.hatchbackCar.color = color;
return this;
}
setEdition(edition: EditionsType): HatchBackProductionLine {
this.hatchbackCar.edition = edition;
return this;
}
setModelToBuild(model: CarCatalog) {
this.modelToCustomizeInLine = model;
}
resetProductionLine() {
this.hatchbackCar =
this.modelToCustomizeInLine === "mastodon"
? new MastodonHatchbackCar()
: new RhinoHatchbackCar();
}
build(): BaseCar {
const hatchbackCar = this.hatchbackCar;
this.resetProductionLine();
return hatchbackCar;
}
}
// STEP 3
class BaseCar {
private _edition!: EditionsType;
private _model!: string;
private _airBags: number = 2;
private _color: AvailableColors = "black";
set airBags(howMany: number) {
this._airBags = howMany;
}
set color(color: AvailableColors) {
this._color = color;
}
set edition(edition: EditionsType) {
this._edition = edition;
}
set model(model: string) {
this._model = model;
}
}
class MastodonSedanCar extends BaseCar {
constructor() {
super();
this.model = "sedan";
}
}
class RhinoSedanCar extends BaseCar {
constructor() {
super();
this.model = "sedan";
}
}
class MastodonHatchbackCar extends BaseCar {
constructor() {
super();
this.model = "hatchback";
}
}
class RhinoHatchbackCar extends BaseCar {
constructor() {
super();
this.model = "hatchback";
}
}
// STEP 4
export class Director {
private productionLine!: CarProductionLine;
setProductionLine(productionLine: CarProductionLine) {
this.productionLine = productionLine;
}
constructCvtEdition(): void {
this.productionLine
.setAirBags(4)
.setColor("sky blue")
.setEdition("cvt");
}
constructSignatureEdition(): void {
this.productionLine
.setAirBags(8)
.setColor("gray")
.setEdition("signature");
}
constructSportEdition(): void {
this.productionLine.setAirBags(1).setColor("white").setEdition("sport");
}
}
type modelCar = "sedan" | "hatchback";
function appBuilder(director: Director, model: modelCar) {
const productionsLines = {
sedan: SedanProductionLine,
hatchback: HatchBackProductionLine,
};
const ProductionLine = productionsLines[model];
const mastodonProductionLine = new ProductionLine({
modelToCustomizeInLine: "mastodon",
});
director.setProductionLine(mastodonProductionLine);
director.constructCvtEdition();
const mastodonModelCvt = mastodonProductionLine.build();
console.log(mastodonModelCvt);
director.constructSignatureEdition();
const mastodonModelSignature = mastodonProductionLine.build();
console.log(mastodonModelSignature);
director.constructSportEdition();
const mastodonModelSport = mastodonProductionLine.build();
console.log(mastodonModelSport);
}
appBuilder(new Director(), "hatchback");
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.