Sou frequentemente confrontado com classes auxiliares ou util em Java ou qualquer tipo de linguagem. Então, eu estava me perguntando se isso é algum tipo de anti-padrão e a existência desse tipo de classe é apenas uma falta de falta no design e na arquitetura de um software.
Frequentemente, essas classes são confinadas usando apenas métodos estáticos, que fazem muitas coisas. Mas, na maioria das vezes, é de fato dependente do contexto e cheio de estado.
Minha pergunta é: qual é a sua opinião sobre esse tipo de classes auxiliares / utilitárias estáticas, porque a vantagem é, obviamente, a chamada rápida usando apenas o nome da classe.
E em que tipo de nível de abstração você evitaria usar esse tipo de classe?
Na minha opinião, a palavra-chave "estático" deve ser permitida apenas dentro da declaração de uma classe (Java) e não para métodos. Na minha opinião, é possível usá-lo dessa maneira, uma boa alternativa e meio caminho para combinar os Paradigmas de Procedimentos e OO em Java e evitar o uso incorreto da palavra-chave.
Acréscimos devido às respostas:
No começo, eu acho que é completamente legal poder combinar paradigmas diferentes e até mesmo usar linguagens de script interpretadas em tempo de execução no código compilado por máquina ou vm.
Minha experiência é que, durante o processo de desenvolvimento de um projeto, esse tipo de ajudante e utilitário, ou qualquer que seja o nome, está crescendo e crescendo e usado em todos os cantos esquecidos da base de código, que foi originalmente projetada para ser modular e flexível. E devido à falta de tempo para fazer refatorações ou pensar novamente no design, você só piora com o tempo.
Eu acho que static
deve ser removido do Java. Especialmente agora, onde é possível usar elementos de linguagem funcional ainda mais sofisticados.
fonte
Respostas:
Bem, Java não possui funções livres, portanto você é forçado a colocá-las como funções estáticas em alguma classe pró-forma. Uma solução alternativa necessária nunca é um antipadrão, embora possa faltar elegância.
Em seguida, não há nada errado com as funções livres. Na verdade, o uso de funções livres reduz o acoplamento, pois eles só têm acesso à interface pública em vez de todos os detalhes sangrentos.
Obviamente, o uso de funções estáticas / livres não diminui de maneira alguma os perigos de um estado compartilhado mutável, especialmente global.
fonte
this
, e exigir algo ser instanciado de forma adequadaUtilitário estático ou funções auxiliares não são um antipadrão se seguirem algumas diretrizes:
Eles devem estar livres de efeitos colaterais
Eles são usados para comportamentos específicos de aplicativos que não pertencem à classe ou classes nas quais essas funções operam
Eles não exigem nenhum estado compartilhado
Casos de uso comuns:
Por exemplo, em um aplicativo em que trabalhei, os usuários mantêm registros de diário para suas atividades. Eles podem especificar uma data de acompanhamento e baixar um lembrete de evento. Criamos uma classe de utilitário estático para obter uma entrada no diário e retornar o texto bruto para um arquivo .ics.
Não exigiu nenhum estado compartilhado. Ele não modificou nenhum estado e a criação de um evento do iCal certamente foi específica do aplicativo e não pertence à classe de entrada no diário.
Se as funções estáticas ou as classes de utilitário tiverem efeitos colaterais ou exigirem um estado compartilhado, recomendo reavaliar esse código, pois ele introduz acoplamentos que podem ser difíceis de zombar para testes de unidade.
fonte
Vai depender da sua abordagem. Muitos aplicativos são escritos com uma mentalidade mais funcional, em oposição à mentalidade clássica (incluindo grande parte do conjunto de sites em que você está).
Com essa mentalidade, haverá muitos métodos utilitários nas classes de trabalho que podem ser agrupados como métodos estáticos. Eles são alimentados / usados mais perto de objetos simples que apenas retêm dados e são transmitidos.
É uma abordagem válida e pode funcionar muito bem, especialmente em escala.
fonte
Agent.Save(obj)
vsagentInstance.Save(obj)
. Com o último, você tem a possibilidade de injetaragentInstance
no código de uso. Em conseqüência, você pode injetar qualquer classe criança deAgent
também que permite a reutilização og o código usando com diferentes "tipos" deAgent
sem recompilar. Isso é baixo acoplamento .Pessoalmente, acho que a única parte importante dessas classes auxiliares é que elas são tornadas privadas. Além disso - são estritamente uma boa ideia (aplicada com moderação).
A maneira como penso sobre isso - é se, ao implementar uma classe (ou função) - algo assim é útil e torna essa implementação mais clara, como isso pode ser ruim? E, muitas vezes, é fundamental definir essas classes auxiliares privadas para permitir a integração e o uso de outros algoritmos que dependem de os dados estarem em uma forma específica.
O fato de rotulá-lo de 'ajudante' é uma pequena questão de gosto pessoal, mas indica que ajuda na implementação e não é de interesse / uso para um público mais amplo. Se é isso que faz sentido - vá em frente!
fonte
java.lang.Math
.A prevalência de
static
classes auxiliares é baseada em um equívoco. Só porque chamamos classes com apenasstatic
métodos "classes utilitárias" não significa que não é permitido escrever comportamento comum em POJOs.static
As classes auxiliares são antipadrão por três razões:O acesso estático a esses métodos auxiliares oculta dependências . Se essas "classes utilitárias" fossem POJOs, você poderia injetá-las int a uma classe dependente como parâmetros construtores, o que tornaria a dependência óbvia para qualquer usuário de uma classe dependente.
O acesso estático a esses métodos auxiliares causa um acoplamento apertado . Isso significa que o código que utiliza os métodos auxiliares é difícil de reutilizar e (como efeito colateral) difícil de testar.
Especialmente se eles mantiverem estado, essas são apenas variáveis globais . E espero que ninguém discuta que variáveis globais são boas ...
As classes auxiliares estáticas fazem parte do anti-padrão do código STUPID .
O OP escreveu:
Construções estáticas statefull são estados globais.
Sim, de causa. E quase todos os aplicativos precisam de algum tipo de estado global .
Mas estado global ! = Variável global .
Você pode criar estado global com técnicas de OO via injeção de dependência. Mas não é possível evitar o estado global com estruturas estáticas cheias de estado, que são variáveis globais na parte inferior.
fonte
Func<Result, Args>
objetos que são instanciados em outro lugar.