Não há nada errado com as classes estáticas que são realmente estáticas . Ou seja, não há um estado interno para se falar, o que faria com que a saída dos métodos mudasse.
Se Dice.roll()
simplesmente retornar um novo número aleatório de 1 a 6, não está mudando de estado. Concedido, você pode estar compartilhando uma Random
instância, mas eu não consideraria que uma mudança de estado, por definição, a saída sempre será boa, aleatória. Também é seguro para threads, portanto não há problemas aqui.
Você verá frequentemente "Helper" final ou outras classes de utilitário que têm um construtor privado e membros estáticos. O construtor privado não contém lógica e serve apenas para impedir que alguém instancia a classe. O modificador final apenas traz essa ideia de que essa não é uma classe da qual você deseja derivar. É apenas uma classe de utilidade. Se feito corretamente, não deve haver singleton ou outros membros da classe que não sejam eles mesmos estáticos e finais.
Contanto que você siga estas diretrizes e não faça singletons, não há absolutamente nada de errado nisso. Você mencionou uma classe de controlador, e isso quase certamente exigirá alterações de estado; portanto, desaconselho o uso apenas de métodos estáticos. Você pode confiar fortemente em uma classe de utilitário estático, mas não pode torná- lo uma classe de utilitário estático.
O que é considerado uma mudança de estado para uma classe? Bem, vamos excluir números aleatórios por um segundo, pois eles não são determinísticos por definição e, portanto, o valor de retorno muda frequentemente.
Uma função pura é aquela que é determinística, ou seja, para uma determinada entrada, você obterá uma e exatamente uma saída. Você deseja que métodos estáticos sejam funções puras. Em Java, existem maneiras de ajustar o comportamento de métodos estáticos para manter o estado, mas quase nunca são boas idéias. Quando você declara um método como estático , o programador típico assume imediatamente que é uma função pura. Desviar-se do comportamento esperado é como você tende a criar bugs no seu programa, geralmente falando e deve ser evitado.
Um singleton é uma classe que contém métodos estáticos tão opostos à "função pura" quanto possível. Um único membro privado estático é mantido internamente na classe que é usada para garantir que exista exatamente uma instância. Esta não é uma prática recomendada e pode causar problemas mais tarde por vários motivos. Para saber do que estamos falando, aqui está um exemplo simples de um singleton:
// DON'T DO THIS!
class Singleton {
private String name;
private static Singleton instance = null;
private Singleton(String name) {
this.name = name;
}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton("George");
}
return instance;
}
public getName() {
return name;
}
}
assert Singleton.getInstance().getName() == "George"