No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

17 Días
19 Hrs
25 Min
46 Seg

Prototype: pros y contras

26/27
Recursos

Aportes 4

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

¡Hola!

Te dejo mi código ejemplo aplicando en typescript el patrón de diseño prototype a una clase de la cuál tiene una relación de composición con otras clases:

class Person {
  private name: string;
  private lastName: string;
  constructor(name, lastName) {
    this.name = name;
    this.lastName = lastName;
  }
  get getName() {
    return this.name;
  }
  get getLastName() {
    return this.lastName;
  }
}

class User {
  private username: string;
  private creationDateUser: string;
  constructor(username) {
    this.username = username;
    const timeInMilisecs = Date.now();
    const date = new Date(timeInMilisecs);
    this.creationDateUser = date.toISOString();
  }
  get getUsername() {
    return this.username;
  }
  get getCreationDateUser() {
    return this.creationDateUser;
  }
}

class UserConfiguration {
  private directory: string;
  private homeFolder: string;
  constructor(directory, homeFolder) {
    this.directory = directory;
    this.homeFolder = homeFolder;
  }
  get getDirectory() {
    return this.directory;
  }
  get getHomeFolder() {
    return this.homeFolder;
  }
}

interface ICompleteUserProps {
  name: string;
  lastName: string;
  username: string;
  directory: string;
  homeFolder: string;
}

class CompleteUser {
  user: User;
  person: Person;
  userConfiguration: UserConfiguration;
  constructor({
    name,
    lastName,
    username,
    directory,
    homeFolder,
  }: ICompleteUserProps) {
    this.person = new Person(name, lastName);
    this.user = new User(username);
    this.userConfiguration = new UserConfiguration(directory, homeFolder);
    console.log('User created successfully, details:\n', this);
  }
  public clone() {
    const props: ICompleteUserProps = {
      name: this.person.getName,
      lastName: this.person.getLastName,
      username: this.user.getUsername,
      directory: this.userConfiguration.getDirectory,
      homeFolder: this.userConfiguration.getHomeFolder,
    };

    return new CompleteUser(props);
  }
}

const createOriginalObjectAndPrototype = ({
  name,
  lastName,
  username,
  directory,
  homeFolder,
}: ICompleteUserProps) => {
  const originalUser = new CompleteUser({
    name,
    lastName,
    username,
    directory,
    homeFolder,
  });
  const userClone = originalUser.clone();
  console.log(
    originalUser === userClone
      ? 'They are the same'
      : 'Different objects, prototype working'
  );
};

createOriginalObjectAndPrototype({
  name: 'Alvaro',
  lastName: 'Garzon',
  username: 'Alvaro8317',
  directory: 'home',
  homeFolder: 'alvaro8317',
});

Si lo prefieres, también subí el código a github

Solución 😄…
Se implementa Rhino y se aumenta engine como un atributo adicional.
.

También pueden compilar código TS en línea, en el siguiente enlace: https://www.typescriptlang.org/play

type AvailableColors = "red" | "black" | "gray" | "default";
type EditionsType = "cvt" | "signature" | "default";
type EngineType = "electric" | "gasoline" | "diesel";
type CarConstructorParams = {
  edition: EditionsType;
  model: string;
  airBags: number;
  color: AvailableColors;
  engine: EngineType;
};
abstract class CarTS {
  private _edition: EditionsType;
  private _model: string;
  private _airBags: number;
  private _color: AvailableColors;
  private _engine: EngineType;

  constructor({
    edition,
    model,
    airBags,
    color,
    engine,
  }: CarConstructorParams) {
    this._edition = edition || "default";
    this._model = model || "";
    this._airBags = airBags || 0;
    this._color = color || "default";
    this._engine = engine || "gasoline";
  }

  set airBags(howMany: number) {
    this._airBags = howMany;
  }

  set color(color: AvailableColors) {
    this._color = color;
  }

  set model(model: string) {
    this._model = model;
  }

  set edition(edition: "cvt" | "signature" | "default") {
    this._edition = edition;
  }

  set engine(type: EngineType) {
    this._engine = type;
  }

  get airBags() {
    return this._airBags;
  }

  get color() {
    return this._color;
  }

  get model() {
    return this._model;
  }

  get edition() {
    return this._edition;
  }

  get engine() {
    return this._engine;
  }

  abstract clone(): CarTS;
}

class MastodonCarTS extends CarTS {
  constructor(carToClone?: MastodonCarTS);
  constructor(carToClone: MastodonCarTS) {
    super({
      edition: carToClone?.edition,
      color: carToClone?.color,
      model: carToClone?.model,
      airBags: carToClone?.airBags,
      engine: carToClone?.engine,
    });
  }

  clone(): MastodonCarTS {
    return new MastodonCarTS(this);
  }
}

class RhinoCarTS extends CarTS {
  constructor(carToClone?: RhinoCarTS);
  constructor(carToClone: RhinoCarTS) {
    super({
      edition: carToClone?.edition,
      color: carToClone?.color,
      model: carToClone?.model,
      airBags: carToClone?.airBags,
      engine: carToClone?.engine,
    });
  }

  clone(): RhinoCarTS {
    return new RhinoCarTS(this);
  }
}

class DirectorTS {
  private productionLine!: CarProductionLineTS;

  setProductionLine(productionLine: CarProductionLineTS) {
    this.productionLine = productionLine;
  }

  constructCvtEdition() {
    this.productionLine.setAirBags(4);
    this.productionLine.setColor("red");
    this.productionLine.setEdition("CVT");
  }

  constructSignatureEdition() {
    this.productionLine.setAirBags(8);
    this.productionLine.setColor("gray");
    this.productionLine.setEdition("signature");
  }
}

interface CarProductionLineTS {
  setAirBags(howMany: number): void;
  setColor(color: AvailableColors): void;
  setEdition(edition: string): void;
  resetProductionLine(car: CarTS): void;
}

type ConstructorParams = { factory: FactoryTS };
class SedanProductionLineTS implements CarProductionLineTS {
  private sedanCar!: CarTS;
  private carFactory!: FactoryTS;

  constructor({ factory }: ConstructorParams) {
    this.carFactory = factory;
    this.resetProductionLine(this.carFactory.create());
  }

  resetProductionLine(car: CarTS): void {
    this.sedanCar = car;
  }

  setAirBags(howMany: number): SedanProductionLineTS {
    this.sedanCar.airBags = howMany;
    return this;
  }

  setColor(color: AvailableColors): SedanProductionLineTS {
    this.sedanCar.color = color;
    return this;
  }

  setEdition(edition: EditionsType): SedanProductionLineTS {
    this.sedanCar.edition = edition;
    return this;
  }

  setModel(): SedanProductionLineTS {
    this.sedanCar.model = "sedan";
    return this;
  }

  setEngine(engine: EngineType): SedanProductionLineTS {
    this.sedanCar.engine = engine;
    return this;
  }

  build(): CarTS {
    this.setModel();
    const sedanCar = this.sedanCar;
    this.resetProductionLine(this.carFactory.create());
    return sedanCar;
  }
}

interface FactoryTS {
  create(): CarTS;
}

class MastodonCarFactoryTS implements FactoryTS {
  create(): CarTS {
    return new MastodonCarTS();
  }
}

class RhinoCarFactoryTS implements FactoryTS {
  create(): CarTS {
    return new RhinoCarTS();
  }
}

function appBuilderTS(director: DirectorTS) {
  const mastodonSedanProductionLine = new SedanProductionLineTS({
    factory: new MastodonCarFactoryTS(),
  });
  director.setProductionLine(mastodonSedanProductionLine);
  director.constructCvtEdition();
  const mastodonSedanCvt = mastodonSedanProductionLine
    .setEngine("diesel")
    .build();
  console.log(mastodonSedanCvt);
  const mastodonSedanCvtPrototype = mastodonSedanCvt.clone();
  console.log(mastodonSedanCvtPrototype);

  director.constructSignatureEdition();
  const mastodonSedanSignature = mastodonSedanProductionLine.build();
  console.log(mastodonSedanSignature);
  const mastodonSedanSignaturePrototype = mastodonSedanSignature.clone();
  console.log(mastodonSedanSignaturePrototype);

  const rhinoSedanProductionLine = new SedanProductionLineTS({
    factory: new RhinoCarFactoryTS(),
  });
  director.setProductionLine(rhinoSedanProductionLine);
  director.constructCvtEdition();
  const rhinoSedanCvt = rhinoSedanProductionLine.setEngine("electric").build();
  console.log(rhinoSedanCvt);
  const rhinoSedanCvtPrototype = rhinoSedanCvt.clone();
  console.log(rhinoSedanCvtPrototype);

  director.constructSignatureEdition();
  const rhinoSedanSignature = rhinoSedanProductionLine.build();
  console.log(rhinoSedanSignature);
  const rhinoSedanSignaturePrototype = rhinoSedanSignature.clone();
  console.log(rhinoSedanSignaturePrototype);
}

appBuilderTS(new DirectorTS());
Yo puedo darles como ejemplo práctico de uso, la clonación de de un objeto para modificarlo en un formulario, si el usuario acepta, el clon remplaza al nuevo, si no se revierte los cambios y se borra el clon.
Excelente, el prototype me resulto algo mas amigable a la hora de poder implementar una dependencia, solamente tendría que pasar la instancia y el objeto estaría clonado, aunque este solamente se utilice para patrones específicos.