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

Extrair Classe.

Problema

Quando uma classe faz o trabalho de duas, surge um desconforto.

Solução

Em vez disso, crie uma nova classe e coloque nela os campos e métodos responsáveis pela funcionalidade relevante.

##Exemplo

Antes
class Person {
  private String name;
  private String officeAreaCode;
  private String officeNumber;

  String getTelephoneNumber() {
    return "(" + officeAreaCode + ") " + officeNumber;
  }
}
Depois
class Person {
  private String name;
  private TelephoneNumber officeTelephone = new TelephoneNumber();

  String getTelephoneNumber() {
    return officeTelephone.getTelephoneNumber();
  }
}
class TelephoneNumber {
  private String areaCode;
  private String number;

  String getTelephoneNumber() {
    return "(" + areaCode + ") " + number;
  }
}

##Por que refatorar

As classes sempre começam claras e fáceis de entender. Elas fazem o seu trabalho e cuidam da própria vida, por assim dizer, sem se intrometer no trabalho de outras classes. Mas, à medida que o programa cresce, um método é adicionado e depois um campo... e, no fim, algumas classes acabam desempenhando mais responsabilidades do que jamais se imaginou.

##Benefícios

  • Este método de refatoração ajudará a manter a aderência ao Princípio da Responsabilidade Única. O código das suas classes ficará mais óbvio e compreensível.

  • Classes com responsabilidade única são mais confiáveis e tolerantes a mudanças. Por exemplo, digamos que você tenha uma classe responsável por dez coisas diferentes. Quando você altera essa classe para torná-la melhor em uma coisa, corre o risco de quebrá-la nas outras nove.

##Como refatorar

Antes de começar, decida exatamente como você quer dividir as responsabilidades da classe.

  1. Crie uma nova classe para conter a funcionalidade relevante.

  2. Crie uma relação entre a classe antiga e a nova. Idealmente, essa relação é unidirecional; isso permite reutilizar a segunda classe sem problemas. No entanto, se você achar que uma relação bidirecional é necessária, ela sempre pode ser estabelecida.

  3. Use Mover Campo e Mover Método para cada campo e método que você decidiu mover para a nova classe. Para os métodos, comece pelos privados, a fim de reduzir o risco de cometer um grande número de erros. Tente realocar apenas um pouco de cada vez e teste os resultados após cada movimentação, para evitar um acúmulo de correções de erros bem no final.

    Depois de terminar a movimentação, dê mais uma olhada nas classes resultantes. Uma classe antiga com responsabilidades alteradas pode ser renomeada para aumentar a clareza. Verifique novamente se você consegue se livrar de relações bidirecionais entre classes, caso alguma esteja presente.

  4. Pense também na acessibilidade à nova classe a partir do exterior. Você pode ocultar a classe completamente do cliente, tornando-a privada e gerenciando-a por meio dos campos da classe antiga. Como alternativa, você pode torná-la pública, permitindo que o cliente altere os valores diretamente. Sua decisão aqui depende de quão seguro é para o comportamento da classe antiga quando mudanças diretas inesperadas são feitas nos valores da nova classe.