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

Substituir Herança por Delegação.

Problema

Você tem uma subclasse que usa apenas uma parte dos métodos de sua superclasse (ou não é possível herdar os dados da superclasse).

Solução

Crie um campo e coloque nele um objeto da superclasse, delegue os métodos ao objeto da superclasse e elimine a herança.

##Exemplo

Antes
class Stack extends Vector {
  void push(Object element) {
    insertElementAt(element, 0);
  }
  Object pop() {
    Object result = firstElement();
    removeElementAt(0);
    return result;
  }
}
Depois
class Stack {
  private Vector elements = new Vector();

  void push(Object element) {
    elements.insertElementAt(element, 0);
  }
  Object pop() {
    Object result = elements.firstElement();
    elements.removeElementAt(0);
    return result;
  }
  boolean isEmpty() {
    return elements.isEmpty();
  }
}

##Por que refatorar

Substituir a herança por composição pode melhorar substancialmente o design da classe se:

  • Sua subclasse viola o princípio de substituição de Liskov, ou seja, se a herança foi implementada apenas para combinar código comum, e não porque a subclasse é uma extensão da superclasse.

  • A subclasse usa apenas uma parte dos métodos da superclasse. Nesse caso, é só questão de tempo até que alguém chame um método da superclasse que não deveria ser chamado.

Em essência, essa técnica de refatoração separa as duas classes e torna a superclasse a auxiliar da subclasse, e não sua progenitora. Em vez de herdar todos os métodos da superclasse, a subclasse terá apenas os métodos necessários para delegar aos métodos do objeto da superclasse.

##Benefícios

  • Uma classe não contém nenhum método desnecessário herdado da superclasse.

  • Vários objetos com diversas implementações podem ser colocados no campo de delegação. Na prática, você obtém o padrão de projeto Strategy.

##Como refatorar

  1. Crie um campo na subclasse para armazenar a superclasse. No estágio inicial, coloque nele o objeto atual.

  2. Altere os métodos da subclasse para que usem o objeto da superclasse em vez de this.

  3. Para os métodos herdados da superclasse que são chamados no código cliente, crie métodos delegadores simples na subclasse.

  4. Remova a declaração de herança da subclasse.

  5. Altere o código de inicialização do campo onde a antiga superclasse é armazenada, criando um novo objeto.