Logotipo do ConstructiCat
CodeBust.
Explorar a seção ▾

Substituir Subclasse por Campos.

Problema

Você tem subclasses que diferem apenas em seus métodos (que retornam constantes).

Solução

Substitua os métodos por campos na classe pai e exclua as subclasses.

##Exemplo

Antes
abstract class Person {
  abstract boolean isMale();
  abstract char getCode();
}
class Male extends Person {
  boolean isMale() { return true; }
  char getCode() { return 'M'; }
}
class Female extends Person {
  boolean isMale() { return false; }
  char getCode() { return 'F'; }
}
Depois
class Person {
  private final boolean male;
  private final char code;

  private Person(boolean male, char code) {
    this.male = male;
    this.code = code;
  }
  static Person createMale() { return new Person(true, 'M'); }
  static Person createFemale() { return new Person(false, 'F'); }
  boolean isMale() { return male; }
  char getCode() { return code; }
}

##Por que refatorar

Às vezes a refatoração é exatamente o que você precisa para evitar código de tipo (type code).

Em um caso assim, uma hierarquia de subclasses pode diferir apenas nos valores retornados por determinados métodos. Esses métodos nem sequer são resultado de algum cálculo, mas estão estritamente definidos nos próprios métodos ou nos campos por eles retornados. Para simplificar a arquitetura da classe, essa hierarquia pode ser comprimida em uma única classe que contém um ou vários campos com os valores necessários, conforme a situação.

Essas mudanças podem se tornar necessárias depois de mover uma grande quantidade de funcionalidade de uma hierarquia de classes para outro lugar. A hierarquia atual já não é tão valiosa e suas subclasses agora são apenas peso morto.

##Benefícios

  • Simplifica a arquitetura do sistema. Criar subclasses é exagero se tudo o que você quer é retornar valores diferentes em métodos diferentes.

##Como refatorar

  1. Aplique Substituir Construtor por Método de Fábrica nas subclasses.

  2. Substitua as chamadas aos construtores das subclasses por chamadas ao método de fábrica da superclasse.

  3. Na superclasse, declare campos para armazenar os valores de cada um dos métodos das subclasses que retornam valores constantes.

  4. Crie um construtor protegido na superclasse para inicializar os novos campos.

  5. Crie ou modifique os construtores existentes das subclasses para que chamem o novo construtor da classe pai e passem a ele os valores relevantes.

  6. Implemente cada método constante na classe pai para que retorne o valor do campo correspondente. Em seguida, remova o método da subclasse.

  7. Se o construtor da subclasse tiver funcionalidade adicional, use Método Embutido para incorporar o construtor ao método de fábrica da superclasse.

  8. Exclua a subclasse.