"Externo" neste contexto significa "observável para os usuários". Os usuários podem ser humanos no caso de um aplicativo ou outros programas no caso de uma API pública.
Portanto, se você mover o método M da classe A para a classe B, e as duas classes estiverem profundamente dentro de um aplicativo, e nenhum usuário puder observar nenhuma alteração no comportamento do aplicativo devido à alteração, poderá chamá-lo de refatoração.
Se, OTOH, algum outro subsistema / componente de nível superior alterar seu comportamento ou interrupções devido à alteração, isso é realmente (geralmente) observável para os usuários (ou pelo menos para os administradores do sistema verificando logs). Ou, se suas classes fizerem parte de uma API pública, pode haver um código de terceiros, que depende de M fazer parte da classe A, e não B. Portanto, nenhum desses casos é refatorado no sentido estrito.
há uma tendência de chamar qualquer retrabalho de código como refatoração, o que eu acho incorreto.
De fato, é uma conseqüência triste, mas esperada, de a refatoração se tornar moda. Os desenvolvedores realizam o retrabalho do código de maneira ad hoc há muito tempo e é certamente mais fácil aprender uma nova palavra da moda do que analisar e mudar hábitos arraigados.
Então, qual é a palavra certa para retrabalhos que alteram o comportamento externo?
Eu chamaria isso de redesenho .
Atualizar
Muitas respostas interessantes sobre a interface, mas a refatoração de métodos não mudaria a interface?
Sobre o que? As classes específicas, sim. Mas essas classes são diretamente visíveis para o mundo exterior de alguma forma? Caso contrário - porque eles estão dentro do seu programa e não fazem parte da interface externa (API / GUI) do programa - nenhuma alteração feita lá é observável por terceiros (a menos que a alteração quebre alguma coisa, é claro).
Sinto que há uma questão mais profunda além disso: existe uma classe específica como entidade independente por si só? Na maioria dos casos, a resposta é não : a classe existe apenas como parte de um componente maior, um ecossistema de classes e objetos, sem o qual não pode ser instanciado e / ou é inutilizável. Esse ecossistema não inclui apenas suas dependências (diretas / indiretas), mas também outras classes / objetos que dependem dele. Isso ocorre porque sem essas classes de nível superior, a responsabilidade associada à nossa classe pode ser sem sentido / inútil para os usuários do sistema.
Por exemplo, em nosso projeto que trata de aluguel de carros, existe uma Charge
classe. Essa classe não tem utilidade para os usuários do sistema por si só, porque os agentes e clientes da estação de aluguel não podem fazer muito com uma cobrança individual: eles lidam com os contratos de contrato de locação como um todo (que incluem vários tipos diferentes de cobrança) . Os usuários estão mais interessados na soma total desses encargos, que devem pagar no final; o agente está interessado nas diferentes opções de contrato, na duração do aluguel, no grupo do veículo, no pacote de seguro, nos itens extras etc. etc. selecionados, que (por meio de regras comerciais sofisticadas) controlam quais cobranças estão presentes e como o pagamento final é calculado fora destes. E os representantes dos países / analistas de negócios se preocupam com as regras comerciais específicas, suas sinergias e efeitos (sobre a receita da empresa, etc.).
Recentemente refatorei essa classe, renomeando a maioria de seus campos e métodos (para seguir a convenção de nomenclatura Java padrão, que foi totalmente negligenciada por nossos antecessores). Eu também pretendo mais refatorações para substituir String
e char
campos com mais apropriado enum
e boolean
tipos. Tudo isso certamente mudará a interface da classe, mas (se eu fizer meu trabalho corretamente) nada disso ficará visível para os usuários do nosso aplicativo. Nenhum deles se importa com a forma como as cobranças individuais são representadas, mesmo sabendo com certeza o conceito de cobrança.. Eu poderia ter selecionado como exemplo uma centena de outras classes que não representam nenhum conceito de domínio, sendo tão conceitualmente invisível para os usuários finais, mas achei mais interessante escolher um exemplo em que haja pelo menos alguma visibilidade no nível do conceito. Isso mostra muito bem que as interfaces de classe são apenas representações de conceitos de domínio (na melhor das hipóteses), não a coisa real *. A representação pode ser alterada sem afetar o conceito. E os usuários apenas têm e entendem o conceito; é nossa tarefa fazer o mapeamento entre conceito e representação.
* E pode-se facilmente acrescentar que o modelo de domínio, que nossa classe representa, é apenas uma representação aproximada de alguma "coisa real" ...