Working with legacy code
Extract Interface Utilizar interface ao invés de classes concretas podem ajudar no design, no polimorfismo  e especialmente em testes.
public class PayTransaction extends Transaction { public PayTransaction ( Database db ,  TransactionRecorder log ) { public void run() { ... } }  }
Parâmetros como  Database db  e  TransactionRecorder log  podem ser opcionais   em um testes, na verdade criaremos superclasses com uma implementação simples ou vazia dos métodos existentes.  Também as interface costumam melhorar o modelo do código, pois pensa-se primeiro nos métodos necessários sem sua implementação e nos parâmetros necessário.
A maioria das IDEs atuais traz ferramentas como Extract Interface. Procure usá-las especialmente quando há muitas implementações da classe. Cuidado com os métodos  estáticos, pois eles não podem fazer parte da interface. Procure extrair os métodos de forma incremental à medida que se escreve testes para os mesmos(Testes da classe final).
Passo a passo Criar a interface com nome apropriado sem nenhum método. Implementar a interface nas classes desejadas Substituir as chamadas das classes pela da interface. O código não irá compilar enquanto não se extrair as assinaturas dos métodos para interface.
Extract Implementer Mesma finalidade de Extract Interface, no entanto, a classe se tornará a Interface e a será criada uma cópia idêntica da classe atual, mas com outro nome.
Razões Em geral o nome da classe atual é o nome ideal para interface, pois é nela que contém a “idéia”, e a classe é como a idéia será executada. Muitos usam prefixos em interfaces, no entanto, é muito ruim trabalhar com tais nomes pois fere o princípio conhecido como “well-named”.
“ This class is too big and I don't want it to get any bigger”
RuleParser - current: string - variables: Hasmap - currentPosition: int + evaluate(string): int + branchExpression(Node left, Node right): int + causalExpression(Node left, Node right): int + variableExpression(Node node): int + nextTerm(): string - hasMoreTerms(): boolean + addVariable(string name, int value)
Em geral, as classe apresentam nomes com prefixos ou sufixos similares como segue abaixo: evaluate branchingExpression nextTerm addVariable causalExpression hasMoreTerms variableExpression valueExpression
RuleEvaluator + evaluate(string) + addVariable(string, int) SymbolTable + addVariable(string, int) RuleParser + parse(string): Expression TermTokenizer + nextTerm(): string + hasMoreTerms: boolean Expression + evaluateWith(SymbolTable)
Heurística Group methods – agrupar métodos por nome ou funcionalidade. É pouco custoso e facilita o entendimento em grandes classes. Look at Hidden Methods – Classes grandes costumam ter diversos métodos privados, se necessário converta-os em públicos para testes. Muitas vezes chega-se a conclusão de criar uma nova classe com esses métodos.
Heurística Look for decisions that can change – foque nas tomadas de decisões dos métodos já criados, verifique se usa conexão com banco de dados, grandes APIs, hard-coded. Look for internal relationships – Em geral classes muito grandes com diversos atributos e métodos não são chamam um pelo outro em todos os lugares, então, conclui que pode-se descobrir quais métodos devem ser testados.
Heurística Look for the Primary Resposibility – Tente descrever uma classe em uma única fase. When all else fails, do some Scratch Refactoring. Focus on the current work – Mude apenas o necessário. Não se trata de uma reforma completa, apenas uma  refatoração suficiente para que haja maior sentimento de confiança na alteração real.
Feature sketch É um esquema muito útil e simples para descobrir o relacionamento interno entre os métodos e atributos das classes.  Agrupa-se os métodos e atributos por similaridade de nome ou funcionalidade.
Reservation - duration: int - dailyRate: int - date: Date - customer: Costumer - fees: List + extend(days) + extendForWeek() + addFee(FeeRider)<<delegates>> - getPrincipalFee(): int + getTotalFee() :int + getAdditionalFee(): int
Esquema da classe Reservation duration getPrincipalFee extend dailyRate extendForWeek date customer getTotalFee getAdditionalFees fees addFee
duration getPrincipalFee extend dailyRate extendForWeek date customer getTotalFee getAdditionalFees fees addFee Métodos aglomerados em Reservation
duration getPrincipalFee extend dailyRate extendForWeek date customer getTotalFee getAdditionalFees fees addFee Métodos aglomerados em outra classe
Interface segragation Principle Grandes classes que implementam interfaces geralmente não usufruem de todos os métodos, então, é mais interessante criar diversas interfaces menores e implementar quantas forem necessárias nas classes.
Ao adicionar novas funcionalidades lembre-se... ...que ao adicionar novas funcionalidades, acima de tudo, o design atual já funcionava. Sejam classes grandes ou sem padrões, elas atualmente exercem funções e muitas vezes de maneira eficiente.
Working with Legacy Code by Michael Feather Recomendação do autor: Livro  Refactoring: Improving the Design of Existing Code  (Martin Fowler)

Working with legacy code 3

  • 1.
  • 2.
    Extract Interface Utilizarinterface ao invés de classes concretas podem ajudar no design, no polimorfismo e especialmente em testes.
  • 3.
    public class PayTransactionextends Transaction { public PayTransaction ( Database db , TransactionRecorder log ) { public void run() { ... } } }
  • 4.
    Parâmetros como Database db e TransactionRecorder log podem ser opcionais em um testes, na verdade criaremos superclasses com uma implementação simples ou vazia dos métodos existentes. Também as interface costumam melhorar o modelo do código, pois pensa-se primeiro nos métodos necessários sem sua implementação e nos parâmetros necessário.
  • 5.
    A maioria dasIDEs atuais traz ferramentas como Extract Interface. Procure usá-las especialmente quando há muitas implementações da classe. Cuidado com os métodos estáticos, pois eles não podem fazer parte da interface. Procure extrair os métodos de forma incremental à medida que se escreve testes para os mesmos(Testes da classe final).
  • 6.
    Passo a passoCriar a interface com nome apropriado sem nenhum método. Implementar a interface nas classes desejadas Substituir as chamadas das classes pela da interface. O código não irá compilar enquanto não se extrair as assinaturas dos métodos para interface.
  • 7.
    Extract Implementer Mesmafinalidade de Extract Interface, no entanto, a classe se tornará a Interface e a será criada uma cópia idêntica da classe atual, mas com outro nome.
  • 8.
    Razões Em geralo nome da classe atual é o nome ideal para interface, pois é nela que contém a “idéia”, e a classe é como a idéia será executada. Muitos usam prefixos em interfaces, no entanto, é muito ruim trabalhar com tais nomes pois fere o princípio conhecido como “well-named”.
  • 9.
    “ This classis too big and I don't want it to get any bigger”
  • 10.
    RuleParser - current:string - variables: Hasmap - currentPosition: int + evaluate(string): int + branchExpression(Node left, Node right): int + causalExpression(Node left, Node right): int + variableExpression(Node node): int + nextTerm(): string - hasMoreTerms(): boolean + addVariable(string name, int value)
  • 11.
    Em geral, asclasse apresentam nomes com prefixos ou sufixos similares como segue abaixo: evaluate branchingExpression nextTerm addVariable causalExpression hasMoreTerms variableExpression valueExpression
  • 12.
    RuleEvaluator + evaluate(string)+ addVariable(string, int) SymbolTable + addVariable(string, int) RuleParser + parse(string): Expression TermTokenizer + nextTerm(): string + hasMoreTerms: boolean Expression + evaluateWith(SymbolTable)
  • 13.
    Heurística Group methods– agrupar métodos por nome ou funcionalidade. É pouco custoso e facilita o entendimento em grandes classes. Look at Hidden Methods – Classes grandes costumam ter diversos métodos privados, se necessário converta-os em públicos para testes. Muitas vezes chega-se a conclusão de criar uma nova classe com esses métodos.
  • 14.
    Heurística Look fordecisions that can change – foque nas tomadas de decisões dos métodos já criados, verifique se usa conexão com banco de dados, grandes APIs, hard-coded. Look for internal relationships – Em geral classes muito grandes com diversos atributos e métodos não são chamam um pelo outro em todos os lugares, então, conclui que pode-se descobrir quais métodos devem ser testados.
  • 15.
    Heurística Look forthe Primary Resposibility – Tente descrever uma classe em uma única fase. When all else fails, do some Scratch Refactoring. Focus on the current work – Mude apenas o necessário. Não se trata de uma reforma completa, apenas uma refatoração suficiente para que haja maior sentimento de confiança na alteração real.
  • 16.
    Feature sketch Éum esquema muito útil e simples para descobrir o relacionamento interno entre os métodos e atributos das classes. Agrupa-se os métodos e atributos por similaridade de nome ou funcionalidade.
  • 17.
    Reservation - duration:int - dailyRate: int - date: Date - customer: Costumer - fees: List + extend(days) + extendForWeek() + addFee(FeeRider)<<delegates>> - getPrincipalFee(): int + getTotalFee() :int + getAdditionalFee(): int
  • 18.
    Esquema da classeReservation duration getPrincipalFee extend dailyRate extendForWeek date customer getTotalFee getAdditionalFees fees addFee
  • 19.
    duration getPrincipalFee extenddailyRate extendForWeek date customer getTotalFee getAdditionalFees fees addFee Métodos aglomerados em Reservation
  • 20.
    duration getPrincipalFee extenddailyRate extendForWeek date customer getTotalFee getAdditionalFees fees addFee Métodos aglomerados em outra classe
  • 21.
    Interface segragation PrincipleGrandes classes que implementam interfaces geralmente não usufruem de todos os métodos, então, é mais interessante criar diversas interfaces menores e implementar quantas forem necessárias nas classes.
  • 22.
    Ao adicionar novasfuncionalidades lembre-se... ...que ao adicionar novas funcionalidades, acima de tudo, o design atual já funcionava. Sejam classes grandes ou sem padrões, elas atualmente exercem funções e muitas vezes de maneira eficiente.
  • 23.
    Working with LegacyCode by Michael Feather Recomendação do autor: Livro Refactoring: Improving the Design of Existing Code (Martin Fowler)