Answer

Answer

t.me/js_test

Ответ:

class PersonBuilder {
  constructor(person) {
    if (person instanceof Person) {
      this.person = person;
    } else {
      this.person = new Person();
    }
  }

  get lives() {
    return new PersonAddressBuilder(this.person);
  }

  get works() {
    return new PersonJobBuilder(this.person);
  }

  build() {
    return this.person;
  }
}

class PersonJobBuilder extends PersonBuilder {
  constructor(person) {
    super(person);
  }

  at(companyName) {
    this.person.companyName = companyName;
    return this;
  }

  asA(position) {
    this.person.position = position;
    return this;
  }

  earning(annualIncome) {
    this.person.annualIncome = annualIncome;
    return this;
  }
}

class PersonAddressBuilder extends PersonBuilder {
  constructor(person) {
    super(person);
  }

  at(streetAddress) {
    this.person.streetAddress = streetAddress;
    return this;
  }

  withPostcode(postcode) {
    this.person.postcode = postcode;
    return this;
  }

  inCity(city) {
    this.person.city = city;
    return this;
  }
}

Объяснение:

Конструктор класса PersonBuilder принимает инстанс класса Person и сохраняет его во внутреннее поле, если же person не был передан то нужно создать свой и тоже сохранить. Геттер lives возвращает инстанс вспомогательного класса PersonAddressBuilder, он наследуется от нашего основного билдера и имеет методы at, withPostcode и inCity которые мутируют поля внутреннего person. Геттер works возвращает инстанс вспомогательного класса PersonJobBuilder, он тоже наследуется от нашего основного билдера и имеет методы at, asA и earning которые тоже мутируют поля внутреннего person. Как видите, реализовав паттерн builder, у нас получилось разделить создание Person на несколько этапов.

Код для проверки:

class Person {
  streetAddress = null;
  postcode = null;
  city = null;
  companyName = null;
  position = null;
  annualIncome = null;

  summary() {
    return `Address: ${this.streetAddress}, ${this.postcode}, ${this.city}
            Employed at ${this.companyName} as a ${this.postcode} earning ${this.annualIncome}`;
  }
}

class PersonBuilder {
  constructor(person) {
    if (person instanceof Person) {
      this.person = person;
    } else {
      this.person = new Person();
    }
  }

  get lives() {
    return new PersonAddressBuilder(this.person);
  }

  get works() {
    return new PersonJobBuilder(this.person);
  }

  build() {
    return this.person;
  }
}

class PersonJobBuilder extends PersonBuilder {
  constructor(person) {
    super(person);
  }

  at(companyName) {
    this.person.companyName = companyName;
    return this;
  }

  asA(position) {
    this.person.position = position;
    return this;
  }

  earning(annualIncome) {
    this.person.annualIncome = annualIncome;
    return this;
  }
}

class PersonAddressBuilder extends PersonBuilder {
  constructor(person) {
    super(person);
  }

  at(streetAddress) {
    this.person.streetAddress = streetAddress;
    return this;
  }

  withPostcode(postcode) {
    this.person.postcode = postcode;
    return this;
  }

  inCity(city) {
    this.person.city = city;
    return this;
  }
}

const personBuilder = new PersonBuilder();
const person = personBuilder
  .lives
    .at("123 London Road")
    .inCity("London")
    .withPostcode("SW12BC")
  .works
    .at("Fabrikam")
    .asA("Engineer")
    .earning(123000)
  .build();

const person2 = new PersonBuilder().build();

console.log(person);
console.log(person2);

Report Page