제이온

[Effective Java] Item 3: Garanta o Singleton com um Construtor Privado ou Tipo Enum

  • Idioma de escrita: Coreana
  • País de referência: Todos os paísescountry-flag
  • TI

Criado: 2024-04-27

Criado: 2024-04-27 00:48

Singleton

Conceito de Singleton

Singleton é uma classe que permite a criação de apenas uma instância. Exemplos típicos de Singleton são objetos sem estado ou componentes únicos do sistema. No entanto, as classes Singleton podem ser difíceis de testar, a menos que o tipo seja definido como uma interface e sua implementação seja definida separadamente.


Como criar um Singleton

Método de membro público estático que é um campo final



O construtor privado é chamado apenas uma vez ao inicializar a instância Elvis, garantindo que ela seja única em todo o sistema. No entanto, é possível chamar o construtor privado usando AccessibleObject.setAccessible(), e essa manipulação por reflexão pode ser bloqueada lançando uma exceção quando um segundo objeto for criado.


  • Vantagens
    • É claro na API que a classe é um Singleton.
    • Conciso.


Método de fábrica estático público fornecido


Exceto pela manipulação por reflexão, este método também garante que haja apenas uma instância em todo o sistema. Ele simplesmente torna o campo privado e usa um método de fábrica estático para retornar o objeto.


  • Vantagens
    • Pode ser alterado para não ser um Singleton sem alterar a API.
      • Por exemplo, o método de fábrica estático pode retornar uma instância diferente para cada thread que o chama.
    • Pode ser alterado para um método de fábrica Singleton genérico, se necessário.
    • A referência de método do método de fábrica estático pode ser usada como um fornecedor.
      • Por exemplo, em vez de Elvis::getInstance, pode ser usado como Supplier<Elvis>.


Se você não precisar usar as vantagens acima, é melhor usar o primeiro método.


Usando um tipo enum


A maneira mais preferível é usar um tipo enum. É mais seguro contra ataques de reflexão e o código é mais limpo do que os dois métodos acima. Além disso, como descrito abaixo, os dois métodos acima têm a desvantagem de exigir código adicional ao serializar.

No entanto, você deve ter cuidado que, embora um Singleton que você deseja criar possa herdar uma interface, ele não pode herdar uma classe.


Pontos a serem observados ao serializar uma classe Singleton

Se você quiser serializar uma classe Singleton criada usando o primeiro ou segundo método acima, além de simplesmente implementar Serializable, você deve declarar todos os campos de instância como transient e substituir o método readResolve() para fornecê-lo.



Fontes

Comentários0