조합을 이용해 객체 통합하기

자전거 부품 조합하기

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/23773eaa-781c-4b18-a406-e51d9024937e/D3A3E243-70D0-4DBC-8EFE-0F0073341B02.png

class Bicycle {
  constructor({ size, parts } = {}) {
    this.size = size;
    this.parts = parts;
  }

  get spares() {
    return this.parts.spares;
  }
}
class Parts {
  constructor(args = {}) {
    this.chain = args.chain || this.defaultChain;
    this.tireSize = args.tireSize || this.defaultTireSize;
    this.postInitialize(args);
  }

  postInitialize(args) {}

  get spares() {
    return {
      tireSize: this.tireSize,
      chain: this.chain,
      ...this.localSpares,
    };
  }

  get defaultTireSize() {
    throw new Error("Not Implemented");
  }

  get defaultChain() {
    return "10-speed";
  }

  get localSpares() {
    return {};
  }
}

class RoadBikeParts extends Parts {
  postInitialize(args) {
    this.tapeColor = args.tapeColor;
  }

  get localSpares() {
    return {
      tapeColor: this.tapeColor,
    };
  }

  get defaultTireSize() {
    return "23";
  }
}

class MountainBikeParts extends Parts {
  postInitialize(args) {
    this.frontShock = args.frontShock;
    this.rearShock = args.rearShock;
  }

  get localSpares() {
    return {
      rearShock: this.rearShock,
    };
  }

  get defaultTireSize() {
    return "2.1";
  }
}
const roadBike = new Bicycle({
  size: "L",
  parts: new RoadBikeParts({ tapeColor: "red" }),
});

console.log(roadBike.size); // => 'L'
console.log(roadBike.spares); // => { tireSize: '23', chain: '10-speed', tapeColor: 'red' }

const mountainBike = new Bicycle({
  size: "L",
  parts: new MountainBikeParts({ rearShock: "Fox" }),
});

console.log(mountainBike.size); // => 'L'
console.log(mountainBike.spares); // => { tireSize: '2.1', chain: '10-speed', rearShock: 'Fox' }

Parts 객체 조합하기

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3891c028-1479-4051-8edd-1e109d1fc514/B43D018F-FF3E-4537-8F77-982761169D7A.png