Diferença entre class estática e padrão singleton?

Que diferença real (prática) existe entre uma class estática e um padrão singleton?

Ambos podem ser invocados sem instanciação, ambos fornecem apenas uma “Instância” e nenhum deles é thread-safe. Existe alguma outra diferença?

O que faz você dizer que um método singleton ou estático não é thread-safe? Normalmente, ambos devem ser implementados para garantir a segurança de threads.

A grande diferença entre um singleton e um monte de methods estáticos é que singletons podem implementar interfaces (ou derivar de classs base úteis, embora isso seja menos comum, na minha experiência), então você pode passar o singleton como se fosse “apenas outro “implementação.

A verdadeira resposta é de Jon Skeet, em outro fórum aqui .

Um singleton permite access a uma única instância criada – essa instância (ou melhor, uma referência a essa instância) pode ser passada como um parâmetro para outros methods e tratada como um object normal.

Uma class estática permite apenas methods estáticos.

  1. Os objects singleton são armazenados no heap , mas os objects estáticos são armazenados na pilha .
  2. Podemos clonar (se o designer não o proibiu) o object singleton, mas não podemos clonar o object de class estático.
  3. As classs singleton seguem o OOP (princípios orientados a objects), as classs estáticas não.
  4. Podemos implementar uma interface com uma class Singleton, mas os methods estáticos de uma class (ou, por exemplo, uma static class C #) não podem.

O padrão Singleton tem várias vantagens sobre as classs estáticas. Primeiro, um singleton pode estender classs e implementar interfaces, enquanto uma class estática não pode (pode estender classs, mas não herda seus membros de instância). Um singleton pode ser inicializado de forma lenta ou assíncrona, enquanto uma class estática é geralmente inicializada quando é carregada pela primeira vez, levando a possíveis problemas de carregadores de classs. Entretanto, a vantagem mais importante é que singletons podem ser manipulados polimorficamente sem forçar seus usuários a assumir que existe apenas uma instância.

classs static não devem fazer nada precisa de estado, é útil para colocar um monte de funções em conjunto, ou seja, Math (ou Utils em projetos). Então o nome da class nos dá uma pista onde podemos encontrar as funções e não há nada mais.

Singleton é o meu padrão favorito e usá-lo para gerenciar algo em um único ponto. É mais flexível que static classs static e pode manter o estado. Ele pode implementar interfaces, herdar de outras classs e permitir inheritance.

Minha regra para escolher entre static e singleton :

Se houver várias funções que devem ser mantidas juntas, então static é a escolha. Qualquer outra coisa que precise de access único a alguns resources poderia ser implementada como singleton .

Classe Estática: –

  1. Você não pode criar a instância da class estática.

  2. Carregado automaticamente pelo Common Language Runtime (CLR) do .NET Framework quando o programa ou namespace que contém a class é carregado.

  3. Classe estática não pode ter construtor.

  4. Não podemos passar a class estática para o método.

  5. Não podemos herdar a class estática para outra class estática em c #.

  6. Uma class com todos os methods estáticos.

  7. Melhor desempenho (methods estáticos são vinculados no tempo de compilation)

Singleton: –

  1. Você pode criar uma instância do object e reutilizá-lo.

  2. A instância do Singleton é criada pela primeira vez quando o usuário solicitou.

  3. A class Singleton pode ter construtor.

  4. Você pode criar o object da class singleton e passá-lo para o método.

  5. A class Singleton não diz qualquer restrição de Herança.

  6. Podemos descartar os objects de uma class singleton, mas não da class estática.

  7. Métodos podem ser substituídos.

  8. Pode ser carregado com preguiça quando necessário (as classs estáticas são sempre carregadas).

  9. Podemos implementar interface (class estática não pode implementar interface).

Uma class estática é aquela que possui apenas methods estáticos, para os quais uma palavra melhor seria “funções”. O estilo de design incorporado em uma class estática é puramente processual.

Singleton, por outro lado, é um padrão específico para o design OO. É uma instância de um object (com todas as possibilidades inerentes a isso, como o polymorphism), com um procedimento de criação que garante que há sempre uma única instância desse papel em particular durante toda a sua existência.

No padrão singleton você pode criar o singleton como uma instância de um tipo derivado, você não pode fazer isso com uma class estática.

Exemplo Rápido:

 if( useD3D ) IRenderer::instance = new D3DRenderer else IRenderer::instance = new OpenGLRenderer 

Para expandir a resposta de Jon Skeet

A grande diferença entre um singleton e um monte de methods estáticos é que singletons podem implementar interfaces (ou derivar de classs base úteis, embora seja um IME menos comum), então você pode passar o singleton como se fosse “apenas outra” implementação.

Singletons são mais fáceis de trabalhar quando a unidade testa uma class. Onde quer que você passe singletons como um parâmetro (construtores, setters ou methods), você pode replace uma versão ridicularizada ou stubbed do singleton.

Outra vantagem de um singleton é que ele pode ser facilmente serializado, o que pode ser necessário se você precisar salvar seu estado em disco ou enviá-lo remotamente.

Eu não sou um ótimo teórico OO, mas pelo que eu sei, eu acho que o único recurso OO que as classs estáticas carecem em comparação com Singletons é o polymorphism. Mas se você não precisa, com uma class estática, você pode ter inheritance (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 class estática é puramente processual” Eu posso estar errado, mas eu discordo. Em methods estáticos, é possível acessar membros estáticos, que seriam exatamente iguais aos methods singleton que acessam seus membros de instância única.

editar:
Na verdade, estou pensando agora que outra diferença é que uma class estática é instanciada no início do programa * e vive durante toda a vida útil do programa, enquanto um singleton é explicitamente instanciado em algum ponto e também pode ser destruído.

* ou pode ser instanciado no primeiro uso, dependendo da linguagem, eu acho.

Aqui está um bom artigo: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

Classes estáticas

  • uma class com todos os methods estáticos .
  • melhor desempenho (methods estáticos são colados no tempo de compilation)
  • não pode replace methods, mas pode usar ocultação de methods. ( O que é o método escondido em Java? Mesmo a explicação do JavaDoc é confusa )

     public class Animal { public static void foo() { System.out.println("Animal"); } } public class Cat extends Animal { public static void foo() { // hides Animal.foo() System.out.println("Cat"); } } 

Solteirão

  • um object que só pode ser instanciado uma vez.
  • methods podem ser sobrescritos ( Por que o Java não permite a substituição de methods estáticos? )
  • mais fácil de zombar, em seguida, methods estáticos
  • melhor em manter o estado

Em resumo, eu só usaria classs estáticas para manter methods util e usar Singleton para todo o resto.


Edições

  • classs estáticas são lazy carregadas também. Obrigado @jmoreno ( Quando a boot da class estática acontece? )

  • ocultação de método para classs estáticas. Obrigado @MaxPeng.

Para ilustrar o ponto de vista de Jon, o que é mostrado abaixo não pode ser feito se o Logger for uma class estática. A class SomeClass espera que uma instância da implementação do ILogger seja passada para seu construtor.

A aula de singleton é importante para que a injeção de dependência seja possível.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { var someClass = new SomeClass(Logger.GetLogger()); } } public class SomeClass { public SomeClass(ILogger MyLogger) { } } public class Logger : ILogger { private static Logger _logger; private Logger() { } public static Logger GetLogger() { if (_logger==null) { _logger = new Logger(); } return _logger; } public void Log() { } } public interface ILogger { void Log(); } } 

Bem, um singleton é apenas uma class normal que é instanciada, mas apenas uma vez e indiretamente a partir do código do cliente. A class estática não é instanciada. Tanto quanto sei, methods estáticos (class estática deve ter methods estáticos) são mais rápidos que não-estáticos.

Editar:
FxCop Descrição da regra de desempenho: “Métodos que não acessam dados de instâncias ou methods de instância de chamada podem ser marcados como estáticos (Shared in VB). Depois disso, o compilador emitirá sites de chamadas não virtuais para esses membros, o que impedirá uma verificação em tempo de execução para cada chamada que garante que o ponteiro do object atual não seja nulo. Isso pode resultar em um ganho de desempenho mensurável para código sensível ao desempenho. Em alguns casos, a falha ao acessar a instância do object atual representa um problema de correção. ”
Eu não sei se isso se aplica também a methods estáticos em classs estáticas.

Singleton’s são instanciados, há apenas uma instância já instanciada, daí o single em Singleton.

Uma class estática não pode ser instanciada por outra coisa senão a si mesma.

Singleton é uma abordagem melhor do ponto de vista de teste. Ao contrário das classs estáticas, o singleton poderia implementar interfaces e você pode usar a instância de simulação e injetá-las.

No exemplo abaixo, vou ilustrar 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 funcionalidade getPrice:

 public class SupportedVersionSingelton { private static ICalculator instance = null; private SupportedVersionSingelton(){ } public static ICalculator getInstance(){ if(instance == null){ instance = new SupportedVersionSingelton(); } return instance; } @Override public int getPrice() { // calculate price logic here return 0; } } 

Uso de getPrice:

 public class Advisor { public boolean isGoodDeal(){ boolean isGoodDeal = false; ICalculator supportedVersion = SupportedVersionSingelton.getInstance(); int price = supportedVersion.getPrice(); // logic to determine if price is a good deal. if(price < 5){ isGoodDeal = true; } return isGoodDeal; } } In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by: Make your singleton implement an interface and inject it. public interface ICalculator { int getPrice(); } 

Implementação Final Singleton:

 public class SupportedVersionSingelton implements ICalculator { private static ICalculator instance = null; private SupportedVersionSingelton(){ } public static ICalculator getInstance(){ if(instance == null){ instance = new SupportedVersionSingelton(); } return instance; } @Override public int getPrice() { return 0; } // for testing purpose public static void setInstance(ICalculator mockObject){ if(instance != null ){ instance = mockObject; } 

class de teste:

 public class TestCalculation { class SupportedVersionDouble implements ICalculator{ @Override public int getPrice() { return 1; } } @Before public void setUp() throws Exception { ICalculator supportedVersionDouble = new SupportedVersionDouble(); SupportedVersionSingelton.setInstance(supportedVersionDouble); } @Test public void test() { Advisor advidor = new Advisor(); boolean isGoodDeal = advidor.isGoodDeal(); Assert.assertEquals(isGoodDeal, true); } } 

Caso tenhamos a alternativa de usar o método estático para implementar getPrice (), foi difícil para o getPrice () de simulação. Você poderia simular a estática com poder de simulação, mas nem todo produto poderia usá-lo.

Eu estou de acordo com esta definição:

A palavra ” single ” significa object único em todo o ciclo de vida do aplicativo, portanto, o escopo está no nível do aplicativo.

A estática não tem nenhum ponteiro de object, portanto, o escopo está no nível do domínio do aplicativo.

Além disso, ambos devem ser implementados para ser thread-safe.

Você pode encontrar outras diferenças interessantes sobre: Singleton Pattern Versus Static Class

Temos nossa estrutura de database que faz conexões com o Back end. Para evitar leituras diretas em vários usuários, usamos o padrão singleton para garantir que tenhamos uma instância única disponível a qualquer momento.

Em c #, uma class estática não pode implementar uma interface. Quando uma única class de instância precisa implementar uma interface para contratos de negócios ou finalidades IoC, é onde eu uso o padrão Singleton sem uma class estática

Singleton fornece uma maneira de manter o estado em cenários sem estado

Espero que ajude você ..

Uma diferença notável é a instanciação diferenciada que vem com Singletons.

Com classs estáticas, ele é criado pelo CLR e não temos controle sobre ele. com singletons, o object é instanciado na primeira instância em que tentou ser acessado.

  1. Carregamento lento
  2. Suporte de interfaces, para que a implementação separada possa ser fornecida
  3. Capacidade de retornar o tipo derivado (como uma combinação de implementação de interface e lazyloading)

Em muitos casos, esses dois não têm nenhuma diferença prática, especialmente se a instância de 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 como oposto a uma class Java somente estática especializada. E por causa disso, um singleton é aceito em muitas outras situações; Na verdade, é a estratégia de instanciação padrão do Spring Framework. O consumidor pode ou não saber que é um singleton sendo passado, apenas trata-o como um bean Java normal. Se o requisito mudar e um singleton precisar se tornar um protótipo, como vemos frequentemente na spring, isso pode ser feito de forma totalmente integrada sem uma mudança de linha de código para o consumidor.

Alguém mencionou anteriormente que uma class estática deveria ser puramente processual, por exemplo, java.lang.Math. Na minha opinião, tal class nunca deve ser passada de um lado para o outro e eles nunca devem ter nada além de final estático como atributos. Para todo o resto, use um singleton, pois é muito mais flexível e fácil de manter.

  • Em c #, uma class estática não pode implementar uma interface. Quando uma única class de instância precisa implementar uma interface por algum motivo comercial ou fins de IoC, você pode usar o padrão Singleton sem uma class estática.
  • Você pode clonar o object de Singleton, mas você não pode clonar o object de class estática
  • O object Singleton é armazenado no Heap, mas o object estático armazena na pilha
  • Um singleton pode ser inicializado de forma lenta ou assíncrona, enquanto uma class estática é geralmente inicializada quando é carregada pela primeira vez

uma. Serialização – membros estáticos pertencem à class e, portanto, não podem ser serializados.

b. Embora tenhamos tornado o construtor privado, as variables ​​de membro estático ainda serão transportadas para a subclass.

c. Não podemos fazer a boot lenta, pois tudo será carregado somente após o carregamento da class.

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á jogando de novo e de novo.

Eu li o seguinte e acho que faz sentido também:

Cuidar dos negócios

Lembre-se, uma das regras OO mais importantes é que um object é responsável por si mesmo. Isso significa que questões relacionadas ao ciclo de vida de uma class devem ser tratadas na class, não delegadas a construções de linguagem como estáticas e assim por diante.

do livro Processo de Pensamento Orientado a Objetos 4ª Ed.

Em um artigo que escrevi, descrevi meu ponto de vista sobre por que o singleton é muito melhor do que uma class estática:

  1. A class estática não é, na verdade, class canônica – é um namespace com funções e variables
  2. A utilização de class estática não é uma boa prática por quebrar princípios de programação orientados a objects
  3. A class estática não pode ser passada como um parâmetro para outra
  4. A class estática não é adequada para boot “lenta”
  5. Inicialização e uso de class estática são sempre rastreados
  6. A implementação do gerenciamento de encadeamentos é difícil

Principais diferenças são:

  • Singleton has an instance/object while static class is a bunch of static methods
  • Singleton can be extended eg through an interface while static class can’t be.
  • Singleton can be inherited which supports open/close principles in SOLID principles on the other hand static class can’t be inherited and we need to make changes in itself.
  • Singleton object can be passed to methods while static class as it does not have instance can’t be passed as parameters

When I want class with full functionality, eg there are many methods and variables, I use singleton;

If I want class with only one or two methods in it, eg MailService class, which has only 1 method SendMail() I use static class and method.

There is a huge difference between a single static class instance (that is, a single instance of a class, which happens to be a static or global variable) and a single static pointer to an instance of the class on the heap:

When your application exits, the destructor of the static class instance will be called. That means if you used that static instance as a singleton, your singleton ceased working properly. If there is still code running that uses that singleton, for example in a different thread, that code is likely to crash.

  1. We can create the object of singleton class and pass it to method.

  2. Singleton class doesn’t any restriction of inheritance.

  3. We can’t dispose the objects of a static class but can singleton class.