Digamos que eu queira criar algumas funções utilitárias para fazer algumas matemáticas básicas com BigDecimal
s, por exemplo, eu quero ter uma função que calcule a média de a List<BigDecimal>
.
Qual é a melhor abordagem? Uma função estática ou uma classe de utilidade?
public static BigDecimal computeAverage(List<BigDecimal> numbers)
ou
public class BigDecimalUtil
public computeAverage(List<BigDecimal> numbers)
Respostas:
Provavelmente vou ceder minhas inclinações C # da pior maneira possível, mas sempre recomendo métodos estáticos nas classes de utilidade. Isso oferece o melhor dos dois mundos. Os benefícios organizacionais da classe com a usabilidade dos métodos acessados sem a necessidade de instanciar um objeto para usá-los. Se a sua classe de utilitário tiver um motivo para ocasionalmente variar seu comportamento, você já estará bem posicionado para fazê-lo, introduzindo a herança / interfaces posteriormente, se necessário. Se você deseja que seu design seja um pouco mais portátil, verá que o paradigma será mais facilmente transferido para outras linguagens OO.
fonte
Se você deseja executar funções utilitárias, conectadas por algum tema, crie uma classe para elas, torne-as estáticas nessa classe e torne um construtor dessa classe privado, para eliminar a possibilidade de ocorrência acidental de uma instância. Portanto, use a segunda variante, mas oculte o construtor.
Há mais uma possibilidade - não fazer construtor e tornar essa classe abstrata. Mas, dessa maneira, você não pode usar a instância da classe não apenas fora, mas também dentro dela. Então, eu acho, essa segunda variante é muito rígida para você. Escolha você mesmo.
fonte
Concordo com o @Gangnus que uma classe estática "wrapper" faz sentido se métodos de classe individuais sempre serão usados isoladamente, e isso geralmente será uma boa resposta.
No entanto, pode haver algum valor em uma classe não estática, com métodos não estáticos, se você tiver cálculos relacionados que provavelmente serão usados juntos. Por exemplo, construir um
ListStatsUtil
objecto comList<BigDecimal>
passado para o construtor, pode ser conveniente para o acessogetStandardDeviation
,getVariance
e,getAverage
em sequência, sem passar para trás no objecto. Isso pode ser mais elegante, mas também pode ter um desempenho melhor, especialmente se estiverem envolvidas operações computacionalmente caras que podem ser otimizadas entre operações, compartilhando o estado privado dentro do objeto.fonte
super()
construtor in private faz sentido para uma classe estática em Java?Votei na resposta do código em voz alta e gostaria de expandir um pouco.
O agrupamento de coleções nas aulas é algo que tentei sempre fazer - minha regra é "nunca passar uma coleção nua". As maiores falhas do OO que eu vi são quando as pessoas têm medo de adicionar métodos a que pertencem. No seu caso, os métodos pertencem à coleção (totalmente obviamente se você pensar sobre isso); portanto, coloque-os lá envolvendo a coleção e para colocar a cobertura no bolo, apenas exponha a funcionalidade necessária fora da sua nova classe (como codingoutloud fez) para que você possa ver sua classe única e pequena e entender facilmente tudo que manipula essa coleção.
Você não precisa resolver todos os problemas possíveis, porque é todo o seu código, você pode editar o wrapper de coleção com a mesma facilidade que você pode editar as outras classes que interagem com ele. Isso permite que você puxe outro código para a classe conforme necessário - se você nunca expuser a coleção, ficará rapidamente óbvio qual código pertence ao wrapper.
Isso também fornece controle total sobre a coleção, para que você possa impedir que ela entre em um estado inconsistente com sua função (por exemplo, se nenhuma entrada na coleção puder ser nula, apenas impeça que alguém coloque uma nula!)
A maior parte do código OO ruim que eu já vi foi criada porque alguém escolheu escrever utilitários estáticos ou código embutido que pertenciam a objetos aos quais não podiam adicionar código, em vez de agrupar os objetos ofensivos em um código próprio que eles poderiam modificar .
fonte
Se não estou errado e o Java considerar uma linguagem OO pura, você não pode ter funções sem agrupá-las em uma classe.
Portanto, sua resposta é: ambas, uma função estática agrupada em uma classe de utilidade estática, não muito diferente da classe Math.
fonte
Que tal uma interface CalcAverageStrategy que é injetada e, em seguida, você pode ter implementações de média / mediana / modo injetadas quando necessário.
Cada implementação é fácil de testar e também fácil de zombar para testes.
fonte