DEV Community

Cover image for Classes (Código Limpo: Que Bruxaria é Essa?!?! - Parte 5)
ananopaisdojavascript
ananopaisdojavascript

Posted on

2 1

Classes (Código Limpo: Que Bruxaria é Essa?!?! - Parte 5)

Prefira as classes do ES2015/ES6 às funções simples

É bem difícil obter herança de classes fácil de ler, construção e definições de métodos para funções clássicas do ES5. Se você precisa da herança (e fique atento porque talvez não precise), priorize as classes do ES2015/ES6. Entretanto, prefira funções pequenas às classes até que você se encontre na necessidade de objetos maiores e mais complexos.

Não é recomendável:

const Animal = function(age) {
  if (!(this instanceof Animal)) {
    throw new Error("Instantiate Animal with `new`");
  }

  this.age = age;
};

Animal.prototype.move = function move() {};

const Mammal = function(age, furColor) {
  if (!(this instanceof Mammal)) {
    throw new Error("Instantiate Mammal with `new`");
  }

  Animal.call(this, age);
  this.furColor = furColor;
};

Mammal.prototype = Object.create(Animal.prototype);
Mammal.prototype.constructor = Mammal;
Mammal.prototype.liveBirth = function liveBirth() {};

const Human = function(age, furColor, languageSpoken) {
  if (!(this instanceof Human)) {
    throw new Error("Instantiate Human with `new`");
  }

  Mammal.call(this, age, furColor);
  this.languageSpoken = languageSpoken;
};

Human.prototype = Object.create(Mammal.prototype);
Human.prototype.constructor = Human;
Human.prototype.speak = function speak() {};
Enter fullscreen mode Exit fullscreen mode

É recomendável:

class Animal {
  constructor(age) {
    this.age = age;
  }

  move() {
    /* ... */
  }
}

class Mammal extends Animal {
  constructor(age, furColor) {
    super(age);
    this.furColor = furColor;
  }

  liveBirth() {
    /* ... */
  }
}

class Human extends Mammal {
  constructor(age, furColor, languageSpoken) {
    super(age, furColor);
    this.languageSpoken = languageSpoken;
  }

  speak() {
    /* ... */
  }
}
Enter fullscreen mode Exit fullscreen mode

Use cadeias de métodos

Esse padrão é bem útil no JavaScript e você o encontra em várias bibliotecas como jQuery e Lodash. Permite que seu código seja expressivo e menos verboso. Por essa razão, eu digo, utilize cadeias de métodos e veja como seu código ficará limpo. Nas suas funções de classes, simplesmente retorne "this" no fim de cada função e você pode encadear métodos de classes mais distantes nela.

Não é recomendável:

class Car {
  constructor(make, model, color) {
    this.make = make;
    this.model = model;
    this.color = color;
  }

  setMake(make) {
    this.make = make;
  }

  setModel(model) {
    this.model = model;
  }

  setColor(color) {
    this.color = color;
  }

  save() {
    console.log(this.make, this.model, this.color);
  }
}

const car = new Car("Ford", "F-150", "red");
car.setColor("pink");
car.save();
Enter fullscreen mode Exit fullscreen mode

É recomendável:

class Car {
  constructor(make, model, color) {
    this.make = make;
    this.model = model;
    this.color = color;
  }

  setMake(make) {
    this.make = make;
    // NOTE: Returning this for chaining
    return this;
  }

  setModel(model) {
    this.model = model;
    // NOTE: Returning this for chaining
    return this;
  }

  setColor(color) {
    this.color = color;
    // NOTE: Returning this for chaining
    return this;
  }

  save() {
    console.log(this.make, this.model, this.color);
    // NOTE: Returning this for chaining
    return this;
  }
}

const car = new Car("Ford", "F-150", "red").setColor("pink").save();
Enter fullscreen mode Exit fullscreen mode

Prefira a composição à herança

De acordo com uma declaração notória em "Design Patterns", escrito pela "Gang of Four", você deve preferir a composição à herança sempre que puder. Há várias boas razões para usar a herança e existem várias boas razões para usar a composição. O ponto principal para essa máxima é que se sua mente, por instinto, pode ir na herança, tente pensar se a composição poderia moldar melhor o seu problema. Em alguns casos pode. Talvez você esteja se perguntando: "quando devo usar a herança?". Depende do seu problema que você tem nas mãos, porém temos uma lista decente de quando o uso da herança faz mais sentido que a composição:

  • Sua herança representa uma relação "é - um" e não uma relação "tem - um" (Humano -> Animal vs. User -> UserDetails)
  • Você pode reusar código das classes base (Humanos podem se mover como todos os animais)
  • Você quer fazer alterações globais em classes derivadas ao mudar uma classe base (Mude o gasto calórico de todos os animais quando se movem)

Não é recomendável:

class Employee {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  // ...
}

// Bad because Employees "have" tax data. EmployeeTaxData is not a type of Employee
class EmployeeTaxData extends Employee {
  constructor(ssn, salary) {
    super();
    this.ssn = ssn;
    this.salary = salary;
  }

  // ...
}
Enter fullscreen mode Exit fullscreen mode

É recomendável:

class EmployeeTaxData {
  constructor(ssn, salary) {
    this.ssn = ssn;
    this.salary = salary;
  }

  // ...
}

class Employee {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  setTaxData(ssn, salary) {
    this.taxData = new EmployeeTaxData(ssn, salary);
  }
  // ...
}
Enter fullscreen mode Exit fullscreen mode

E aí? Gostaram? Até a próxima tradução! 🤗

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more