Que diferença real (prática) existe entre uma classe estática e um padrão singleton?
Ambos podem ser chamados sem instanciação, ambos fornecem apenas uma "Instância" e nenhum deles é seguro para threads. Existe alguma outra diferença?
design-patterns
static
singleton
Jorge Córdoba
fonte
fonte
getInstance()
método toda vez que você quiser usá-lo (embora provavelmente na maioria dos casos isso não importe ).singleton
objeto em questatic
métodos são apenas funções, uma entidade não OO.Respostas:
O que faz você dizer que um método singleton ou estático não é seguro para threads? Geralmente, ambos devem ser implementados para serem seguros para threads.
A grande diferença entre um singleton e vários métodos estáticos é que singletons podem implementar interfaces (ou derivar de classes base úteis, embora isso seja menos comum na minha experiência), para que você possa passar pelo singleton como se fosse "apenas mais um "implementação.
fonte
Foo
, e você tem um método usando aFoo
como parâmetro. Com essa configuração, os chamadores podem optar por usar o singleton como a implementação - ou podem usar uma implementação diferente. O método é dissociado do singleton. Compare isso com a situação em que a classe apenas possui métodos estáticos - cada parte do código que deseja chamar esses métodos está fortemente acoplada à classe, porque precisa especificar qual classe contém os métodos estáticos.A verdadeira resposta é de Jon Skeet, em outro fórum aqui .
fonte
interface
com uma classe Singleton, mas os métodos estáticos de uma classe (ou por exemplo, um C #static class
) não podem.fonte
O padrão Singleton tem várias vantagens sobre as classes estáticas. Primeiro, um singleton pode estender classes e implementar interfaces, enquanto uma classe estática não pode (pode estender classes, mas não herda seus membros da instância). Um singleton pode ser inicializado de forma lenta ou assíncrona, enquanto uma classe estática é geralmente inicializada quando é carregada pela primeira vez, levando a possíveis problemas no carregador de classes. No entanto, a vantagem mais importante, porém, é que singletons podem ser manipulados polimorficamente, sem forçar seus usuários a supor que existe apenas uma instância.
fonte
static
classes não são para nada que precise de estado. É útil para reunir várias funções, isto é,Math
(ouUtils
em projetos). Portanto, o nome da classe nos dá uma pista de onde podemos encontrar as funções e nada mais.Singleton
é o meu padrão favorito e eu o uso para gerenciar algo em um único ponto. É mais flexível que asstatic
classes e pode manter seu estado. Ele pode implementar interfaces, herdar de outras classes e permitir herança.Minha regra para escolher entre
static
esingleton
:Se houver várias funções que devem ser mantidas juntas, então
static
é a escolha. Qualquer outra coisa que precise de acesso único a alguns recursos pode ser implementada como asingleton
.fonte
State
é a combinação de diferentes propriedades de um objeto que geralmente muda com o tempo. Você pode procurar no Google por definição formal.Classe estática: -
Você não pode criar a instância da classe estática.
Carregado automaticamente pelo CLR (Common Language Runtime) do .NET Framework quando o programa ou espaço para nome que contém a classe é carregado.
Classe estática não pode ter construtor.
Não podemos passar a classe estática para o método
Não podemos herdar a classe Static para outra classe Static em C #.
Uma classe com todos os métodos estáticos.
Melhor desempenho (métodos estáticos são ligados em tempo de compilação)
Singleton: -
Você pode criar uma instância do objeto e reutilizá-lo.
A instância Singleton é criada pela primeira vez quando o usuário solicitou.
A classe Singleton pode ter construtor.
Você pode criar o objeto da classe singleton e passá-lo ao método
A classe Singleton não diz nenhuma restrição de herança.
Podemos descartar os objetos de uma classe singleton, mas não da classe estática.
Métodos podem ser substituídos.
Pode ser carregado com preguiça quando necessário (as classes estáticas são sempre carregadas).
Nós podemos implementar interface (classe estática não pode implementar interface).
fonte
Uma classe estática é aquela que possui apenas métodos estáticos, para os quais uma palavra melhor seria "funções". O estilo de design incorporado em uma classe estática é puramente processual.
Singleton, por outro lado, é um padrão específico para o projeto OO. É uma instância de um objeto (com todas as possibilidades inerentes a isso, como o polimorfismo), com um procedimento de criação que garante que haja apenas uma instância dessa função específica durante toda a sua vida útil.
fonte
No padrão singleton, você pode criar o singleton como uma instância de um tipo derivado; não é possível fazer isso com uma classe estática.
Exemplo rápido:
fonte
Para expandir a resposta de Jon Skeet
Os singletons são mais fáceis de trabalhar ao testar uma unidade. Onde quer que você passe singletons como parâmetro (construtores, configuradores ou métodos), você pode substituir uma versão zombada ou stubbed do singleton.
fonte
MySingleton mockOfMySingleton = mock(MySingleton.class)
.new ClazzToTest(mockSingleton);
Aqui está um bom artigo: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
Classes estáticas
não pode substituir métodos, mas pode usar a ocultação de métodos. ( O que é método oculto em Java? Até a explicação JavaDoc é confusa )
Singleton
Em resumo, eu usaria apenas classes estáticas para armazenar métodos util e usar Singleton para todo o resto.
Editar% s
classes estáticas também são carregadas com preguiça. Thanks @jmoreno ( Quando é que a inicialização da classe estática acontece? )
método oculto para classes estáticas. Obrigado @MaxPeng.
fonte
Animal animal = new Cat();
então oanimal.foo();
que acontece?Outra vantagem de um singleton é que ele pode ser serializado facilmente, o que pode ser necessário se você precisar salvar seu estado em disco ou enviá-lo para algum lugar remotamente.
fonte
Não sou um grande teórico de OO, mas pelo que sei, acho que o único recurso de OO que falta às classes estáticas em comparação aos Singletons é o polimorfismo. Mas se você não precisar, com uma classe estática, é claro que você pode ter herança (não tenho certeza sobre a implementação da interface) e encapsulamento de dados e funções.
O comentário de Morendil: "O estilo de design incorporado em uma classe estática é puramente processual". Posso estar errado, mas discordo. Nos métodos estáticos, você pode acessar membros estáticos, o que seria exatamente o mesmo que os métodos singleton que acessam seus membros de instância única.
edit:
Na verdade, estou pensando agora que outra diferença é que uma classe estática é instanciada no início do programa * e vive por toda a vida útil do programa, enquanto um singleton é instanciado explicitamente em algum momento e pode ser destruído também.
* ou pode ser instanciado no primeiro uso, dependendo do idioma, eu acho.
fonte
Para ilustrar o ponto de Jon, o que é mostrado abaixo não pode ser feito se o Logger for uma classe estática. A classe
SomeClass
espera que uma instância deILogger
implementação seja passada para seu construtor.A classe Singleton é importante para que a injeção de dependência seja possível.
fonte
Bem, um singleton é apenas uma classe normal que é instanciada, mas apenas uma vez e indiretamente do código do cliente. A classe estática não é instanciada. Tanto quanto eu sei, os métodos estáticos (a classe estática deve ter métodos estáticos) são mais rápidos que os não estáticos.
Editar:
Descrição da regra de desempenho do FxCop: "Métodos que não acessam dados da instância ou métodos de instância da chamada podem ser marcados como estáticos (compartilhados no VB). Depois disso, o compilador emitirá sites de chamada não virtuais para esses membros, o que impedirá um verifique no tempo de execução cada chamada que assegura que o ponteiro do objeto atual não seja nulo. Isso pode resultar em um ganho mensurável de desempenho para código sensível ao desempenho. Em alguns casos, a falha ao acessar a instância atual do objeto representa um problema de correção. "
Na verdade, não sei se isso se aplica também a métodos estáticos em classes estáticas.
fonte
Singleton é instanciado, é que só existe uma instância já instanciada, daí o single em Singleton.
Uma classe estática não pode ser instanciada por nada além de si mesma.
fonte
As principais diferenças são:
fonte
Singleton é uma melhor abordagem da perspectiva de teste. Diferentemente das classes estáticas, o singleton pode implementar interfaces e você pode usar uma instância simulada e injetá-las.
No exemplo abaixo, ilustrarei isso. Suponha que você tenha um método isGoodPrice () que use um método getPrice () e implemente getPrice () como um método em um singleton.
singleton que fornece a funcionalidade getPrice:
Uso de getPrice:
Implementação final de Singleton:
classe de teste:
Caso tomemos a alternativa de usar o método estático para implementar o getPrice (), foi difícil para o mock getPrice (). Você pode simular a estática com a simulação de energia, mas nem todos os produtos podem usá-lo.
fonte
Estou de acordo com esta definição:
Você pode encontrar outras diferenças interessantes sobre: Padrão Singleton versus classe estática
fonte
Uma diferença notável é a instanciação diferente que vem com os Singletons.
Com classes estáticas, ele é criado pelo CLR e não temos controle sobre ele. com singletons, o objeto é instanciado na primeira instância em que tenta ser acessado.
fonte
Em muitos casos, esses dois não têm diferença prática, especialmente se a instância singleton nunca muda ou muda muito lentamente, por exemplo, mantendo configurações.
Eu diria que a maior diferença é que um singleton ainda é um Java Bean normal, em oposição a uma classe Java apenas estática especializada. E por causa disso, um singleton é aceito em muitas outras situações; é de fato a estratégia de instanciação padrão do Spring Framework. O consumidor pode ou não saber que está sendo transmitido um singleton, apenas o trata como um Java bean normal. Se os requisitos mudarem e um singleton precisar se tornar um protótipo, como costumamos ver no Spring, isso pode ser feito de maneira totalmente transparente, sem uma linha de alteração de código para o consumidor.
Outra pessoa mencionou anteriormente que uma classe estática deve ser puramente processual, por exemplo, java.lang.Math. Na minha opinião, essa classe nunca deve ser contornada e nunca deve conter nada além de estática final como atributos. Para todo o resto, use um singleton, pois é muito mais flexível e fácil de manter.
fonte
Temos nossa estrutura de banco de dados que faz conexões com o back-end. Para evitar leituras sujas em vários usuários, usamos o padrão singleton para garantir que tenhamos uma única instância disponível a qualquer momento.
Em c #, uma classe estática não pode implementar uma interface. Quando uma classe de instância única precisa implementar uma interface para contratos de negócios ou fins de IoC, é aqui que eu uso o padrão Singleton sem uma classe estática
Singleton fornece uma maneira de manter o estado em cenários sem estado
Espero que ajude você ..
fonte
fonte
uma. Serialização - membros estáticos pertencem à classe e, portanto, não podem ser serializados.
b. Embora tenhamos tornado o construtor privado, as variáveis de membro estático ainda serão transportadas para a subclasse.
c. Não podemos fazer uma inicialização lenta, pois tudo será carregado apenas no carregamento da classe.
fonte
Da perspectiva do cliente, o comportamento estático é conhecido pelo cliente, mas o comportamento Singleton pode ser concluído oculto de um cliente. O cliente pode nunca saber que existe apenas uma única instância com a qual ele está brincando repetidamente.
fonte
Eu li o seguinte e acho que também faz sentido:
do livro Processo de Pensamento Objetivo-Orientado 4th Ed.
fonte
Em um artigo que escrevi, descrevi meu ponto de vista sobre por que o singleton é muito melhor do que uma classe estática:
fonte
Podemos criar o objeto da classe singleton e passá-lo ao método
A classe Singleton não tem nenhuma restrição de herança.
Não podemos descartar os objetos de uma classe estática, mas podemos singleton.
fonte
Distinção da classe estática
O JDK tem exemplos de singleton e estático, por um lado,
java.lang.Math
é uma classe final com métodos estáticos, por outro lado,java.lang.Runtime
é uma classe singleton.Vantagens de singleton
Se a sua necessidade de manter o estado do que o padrão singleton for uma escolha melhor do que a classe estática, porque a manutenção do estado na classe estática leva a erros, especialmente em ambientes simultâneos, que podem levar a condições de corrida sem modificação paralela de sincronização adequada por vários encadeamentos.
A classe Singleton pode ser carregada com preguiça se for um objeto pesado, mas a classe estática não tem essas vantagens e sempre é carregada com avidez.
Com o singleton, você pode usar herança e polimorfismo para estender uma classe base, implementar uma interface e fornecer diferentes implementações.
Como os métodos estáticos em Java não podem ser substituídos, eles levam à inflexibilidade. Por outro lado, você pode substituir os métodos definidos na classe singleton estendendo-a.
Desvantagens da classe estática
Vantagens da classe estática
Existem várias realizações do padrão singleton, cada uma com vantagens e desvantagens.
Descrição detalhada de cada uma delas é muito detalhada, por isso, basta colocar um link para um bom artigo - Tudo o que você quer saber sobre Singleton
fonte
Há uma enorme diferença entre uma única instância de classe estática (ou seja, uma única instância de uma classe, que passa a ser uma variável estática ou global) e um único ponteiro estático para uma instância da classe no heap:
Quando o aplicativo sair, o destruidor da instância de classe estática será chamado. Isso significa que, se você usou essa instância estática como um singleton, seu singleton deixou de funcionar corretamente. Se ainda houver um código em execução que use esse singleton, por exemplo, em um encadeamento diferente, é provável que esse código falhe.
fonte
A diferença na minha cabeça é implementar programação orientada a objetos (Singleton / Prototype) ou programação funcional (estática).
Estamos muito focados no número de objetos criados pelo padrão singleton quando o que devemos focar é que, no final, mantemos um objeto. Como outros já disseram, ele pode ser estendido, passado como um parâmetro, mas o mais importante é que está cheio de estado.
Por outro lado, a estática é usada para implementar a programação funcional. Os membros estáticos pertencem a uma classe. Eles são apátridas.
A propósito, você sabia que pode criar classes estáticas singleton :)
fonte