Композиция с растопыренными предметами - PullRequest
1 голос
/ 31 января 2020

Я смотрел учебник по композиции, и он заставляет вас сочинять такие объекты:

const eater = (state) => ({
  eat(amount) {
    console.log(state.name + ' is eating');
    state.energy += amount;
  }
});

// using a factory
const Dog = (name, energy, breed) => {
  let dog = {
    name,
    energy,
    breed
  };
  return Object.assign(dog, eater(dog));
};

const leo = Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20

Мне было бы интересно, если бы вы могли сделать что-то подобное вместо этого, и есть ли какие-либо недостатки этого сделать:

const eater = {
  eat(amount) {
    console.log(this.name + ' is eating');
    this.energy += amount;
  }
};

const Dog = (name, energy, breed) => {
  let dog = {
    name,
    energy,
    breed,
    ...eater
  };
  return dog;
};

const leo = Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20

Как видите, вместо создания и назначения функции для объекта с помощью Object.assign я создаю другой объект eater с помощью метода, а затем распространяю этот eater объект и добавьте его к dog объекту, создаваемому внутри фабрики.

Итак, что-то не так с этим?

Спасибо!

1 Ответ

2 голосов
/ 09 февраля 2020

Эти два подхода очень похожи. Оба варианта работоспособны и хороши.

Вот различия:

  • Первый подход: eater - заводская функция

    • Новый eater объект и eat функция создаются для каждого dog
    • eat привязанного метода:

      let leoEat = leo.eat;
      leoEat(10); //works
      
  • Второй подход: eater - это объект

    • Объект eater и функция eat повторно используются
    • eat isn ' T Граница:

      const leo = Dog('Leo', 10, 'Pug');
      const animal = {name: 'Animal', energy: 0};
      leo.eat.call(animal, 30); // Animal is eating
      console.log(animal.energy); // 30
      console.log(leo.energy); // 10
      
  • Третий подход (да, есть!): Eater и Dog являются классами

    • Функция eat используется повторно
    • eat не связана
    • Использует прототипы
    • Не поддерживает множественное наследование

class Eater {
  eat(amount) {
    console.log(this.name + ' is eating');
    this.energy += amount;
  }
};

class Dog extends Eater{
  constructor (name, energy, breed) {
    super();
    Object.assign(this, {
      name,
      energy,
      breed
    })
  }
};

const leo = new Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20
console.log(leo instanceof Dog) //true
console.log(leo instanceof Eater) //true
...