Tentarei dar uma resposta contra esse uso, depois de ter visto e trabalhado nisso em um dos meus projetos também.
Legibilidade do código
Antes de tudo, considere que a legibilidade do código é importante e essa prática é contrária a isso. Alguém lê um pedaço de código e digamos que ele tem uma função doSomething(Employee e)
. Isso não é mais legível, porque, devido às 10 Employee
classes diferentes existentes em pacotes diferentes, você precisará primeiro recorrer à declaração de importação para descobrir qual é realmente a sua entrada.
Essa é, no entanto, uma visão de alto nível e, geralmente, temos conflitos de nomes aparentemente aleatórios, com os quais ninguém se importa ou que encontra, porque o significado pode ser derivado do código restante e do pacote em que você está. Portanto, pode-se argumentar que, localmente, não há problema, porque é claro que, se você vir Employee
dentro de um hr
pacote, precisará saber que estamos falando de uma visão de RH do funcionário.
As coisas se desfazem assim que você deixa esses pacotes. Depois de trabalhar em um módulo / pacote / etc diferente e precisar trabalhar com um funcionário, você já estará sacrificando a legibilidade se não qualificar totalmente seu tipo. Além disso, ter 10 Employee
classes diferentes significa que o preenchimento automático do IDE não funcionará mais e você deverá escolher manualmente o tipo de funcionário.
Duplicação de código
Devido à natureza de cada uma dessas classes estar relacionada entre si, seu código provavelmente se deteriorará devido a muita duplicação. Na maioria dos casos, você terá algo como o nome de um funcionário ou algum número de identificação, que cada uma das classes precisa implementar. Embora cada classe inclua seu próprio tipo de visão, se elas não compartilharem os dados subjacentes dos funcionários, você terá uma enorme quantidade de códigos inúteis, mas caros.
Complexidade do código
O que pode ser tão complexo que você pode perguntar? Afinal, cada uma das classes pode mantê-lo tão simples quanto desejar. O que realmente se torna um problema é como você propaga as mudanças. Em um software razoavelmente rico em recursos, você pode alterar os dados dos funcionários - e deseja refletir isso em qualquer lugar. Digamos que uma senhora acabou de se casar e você precise renomeá-la de X
paraY
devido a isso. Difícil o suficiente para fazer isso em todos os lugares, mas ainda mais quando você tem todas essas classes distintas. Dependendo de suas outras opções de design, isso pode facilmente significar que cada uma das classes precisa implementar seu próprio tipo de ouvinte ou ser notificado sobre alterações - o que basicamente se traduz em um fator aplicado ao número de classes com as quais você deve lidar. . E mais duplicação de código, é claro, e menos legibilidade de código. Fatores como esse podem ser ignorados na análise de complexidade, mas certamente são irritantes quando aplicados ao tamanho da sua base de código.
Comunicação de código
Além dos problemas acima com a complexidade do código, que também estão relacionados às opções de design, você também reduz a clareza de design de nível superior e perde a capacidade de se comunicar adequadamente com especialistas em domínio. Ao discutir arquitetura, projetos ou requisitos, você não é mais livre para fazer declarações simples como given an employee, you can do ...
. Um desenvolvedor não saberá mais o que employee
realmente significa nesse momento. Embora um especialista em domínio saiba disso, é claro. Todos nós fazemos. tipo de. Mas, em termos de software, não é mais tão fácil se comunicar.
Como se livrar do problema
Depois de tomar conhecimento disso e se sua equipe concordar que é um problema grande o suficiente para ser resolvido, você terá que encontrar uma maneira de lidar com isso. Normalmente, você não pode pedir ao seu gerente que dê uma semana inteira à equipe para que ele possa retirar o lixo. Portanto, em essência, você terá que encontrar uma maneira de eliminar parcialmente essas classes, uma de cada vez. A parte mais importante disso é decidir - com toda a equipe - o que Employee
realmente é. Você não integrar todos os atributos individuais em um deus-empregado. Pense mais em um funcionário principal e, mais importante, decida onde essa Employee
classe residirá.
Se você faz revisões de código, é particularmente fácil garantir que o problema não melhore ainda mais, ou seja, interrompa todo mundo no caminho certo quando quiser adicionar outro Employee
novamente. Também verifique se os novos subsistemas aderem ao acordado Employee
e não têm permissão para acessar as versões antigas.
Dependendo da sua linguagem de programação, convém marcar as classes que eventualmente serão eliminadas com algo como @Deprecated
para ajudar sua equipe a perceber imediatamente que eles estão trabalhando com algo que precisará ser alterado.
Quanto a se livrar das classes de funcionários desatualizadas, você pode decidir, para cada caso individual, como é melhor eliminá-las ou simplesmente concordar com um padrão comum. Você pode afixar o nome da classe e envolvê-lo em torno do funcionário real, pode usar padrões (decorador ou adaptador), ou, ou ou.
Para resumir uma longa história: Essa "prática" é tecnicamente sólida, mas está cheia de custos ocultos que só ocorrerão mais adiante. Embora você não consiga se livrar imediatamente do problema, você pode começar imediatamente contendo os efeitos nocivos.