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


1768

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?


4
Dependendo da implementação do idioma e dos seus padrões de uso, um Singleton pode ser menos eficiente devido à sobrecarga de chamar o getInstance()método toda vez que você quiser usá-lo (embora provavelmente na maioria dos casos isso não importe ).
Php demais php

5
Já existem muitas respostas. Na verdade, é um singletonobjeto em que staticmétodos são apenas funções, uma entidade não OO.
fastcodejava

4
VJAI

4
Há uma diferença quando você deseja permitir que terceiros forneçam a implementação da classe. Nesse caso, você normalmente também precisa de padrões de fábrica. Veja agiletribe.wordpress.com/2013/10/08/…
AgilePro

IMO esta resposta resume muito bem stackoverflow.com/questions/14097656/…
Dave

Respostas:


1251

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.


29
Bem, se você preferir, também não é inerentemente seguro para threads, você precisa torná-los seguros para ambos, para que não haja diferença.
Jorge Córdoba

119
Você pode dar um exemplo de algo que é inerentemente seguro para threads, exceto tipos imutáveis?
6119 Jon Skeet

26
Para o Skeet: as pessoas que dizem que o singleton não é seguro para threads significa que um singleton é compartilhado desnecessariamente entre threads o tempo todo, enquanto objetos de pilha são compartilhados quando você precisar, o que significa que você não precisa fazer sincronizações desnecessárias.

45
@ Geek: Imagine o singleton implementa uma interface Foo, e você tem um método usando a Foocomo 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.
Jon Skeet

10
@AmirBareket: embora não seja um singleton de acordo com o padrão de design do singleton - se a própria classe permite a criação de várias instâncias, não é um IMO de singleton, independentemente do que a fábrica faça.
Jon Skeet

476

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

Um singleton permite o acesso a uma única instância criada - essa instância (ou melhor, uma referência a essa instância) pode ser passada como parâmetro para outros métodos e tratada como um objeto normal.

Uma classe estática permite apenas métodos estáticos.


64
Por que você passaria um Singleton como parâmetro, se você pode acessar a mesma instância de qualquer lugar chamando o método estático getInstance ()?
Henrique Ordine

23
@HenriqueOrdine Para que ele possa se encaixar no código existente e fornecer uma interface?

6
@HenriqueOrdine Eles estão falando sobre classe estática, não uma classe com métodos estáticos. A classe estática não pode ser instanciada. No entanto, se você passar uma instância de uma classe (não estática) que contém métodos estáticos, não poderá chamar métodos estáticos em uma instância.
Goran

3
O que é uma classe estática? Pelo menos em Java, não existe.
Henrique Ordine

16
@ Koran Inicialmente fiquei muito confuso com sua redação. Você disse "você não pode chamar métodos estáticos em uma instância". Eu li que "se você tem uma referência a um objeto instanciado, não pode chamar nenhum método estático que ele possa ter". Isso é claro, incorreto. Depois de ler novamente algumas vezes, acho que você quis dizer "de dentro de métodos estáticos, não é possível acessar objetos não estáticos na classe", o que está correto. Deseja esclarecer que qualquer pessoa nova nesses conceitos se depara com essa resposta e lê seus comentários.
Andrew Steitz

359
  1. Objetos singleton são armazenados na pilha , mas objetos estáticos são armazenados na pilha .
  2. Podemos clonar (se o designer não o proibir) o objeto singleton, mas não podemos clonar o objeto de classe estática.
  3. As classes Singleton seguem o OOP (princípios orientados a objetos), as classes estáticas não.
  4. Podemos implementar um interfacecom uma classe Singleton, mas os métodos estáticos de uma classe (ou por exemplo, um C # static class) não podem.

99
A segunda afirmação está errada. Não podemos clonar objeto Singleton. A implementação Singleton deve recusar isso. Se você realmente pode clonar Singleton, não é Singleton.
Alexander Yancharuk

19
Esta é a resposta não está correta para Java: nem o singleton nem o estático usam a pilha.
AgilePro

72
# 1 não é importante. # 2 descreve uma implementação defeituosa. # 3 é completamente injustificável.
Casey

31
Como o objeto estático pode ser armazenado na pilha? O novo quadro de pilha é criado quando você invoca um método, ele armazena as variáveis ​​locais do método, esse quadro de pilha é removido quando o método retorna e essas variáveis ​​locais são perdidas. A pilha certa é rápida, mas não é adequada para armazenar objetos estáticos.
Mike_m

23
Eu não consigo entender o número de votos neste. 1) Por que Singleton deve ser armazenado na pilha? Em linguagens gerenciadas como C # ou Java, os dados são armazenados em um heap gerenciado, exceto para variáveis ​​/ parâmetros locais do método. 2) Se você pode cloná-lo, não é um singleton implementado corretamente. 3) Singleton é conhecido como anti-padrão OOP; ou seja, algo que você deve evitar, se possível. 4) Essa é a única coisa correta.
Groo

152

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.


10
+1 para obter pontos positivos e pragmáticos. O padrão Singleton é usado em geral, mas há algumas situações em que é apropriado. Veja também: agiletribe.wordpress.com/2013/10/08/…
AgilePro 20/13

3
Você está certo sobre a vantagem de ser polimórfico. Este é o ponto mais importante
Ahmad

A classe estática aninhada pode implementar a interface. Tente codificá-lo, irá funcionar. Eu poderia compilar o código sem nenhum erro.
Nanosoft

75

staticclasses não são para nada que precise de estado. É útil para reunir várias funções, isto é, Math(ou Utilsem 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 as staticclasses e pode manter seu estado. Ele pode implementar interfaces, herdar de outras classes e permitir herança.

Minha regra para escolher entre statice singleton:

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 a singleton.


16
Por que as classes estáticas não devem fazer nada que precise salvar o estado?
Trisped

12
@Trisped: Você não tem controle preciso sobre a inicialização nem a finalização.
Xaqron

7
você me perdeu no "Singleton é o meu padrão favorito". Singleton é uma esquina tão acentuada que deve ser considerada um antipadrão e também um padrão. As classes podem muito bem ter estados estáticos, isso também é acesso único, se qualquer estado estático for mais "acesso único" que singletons, porque a maioria das implementações singleton está quebrada. você pode clonar o singleton, enquanto estática é abençoada pela definição de ser única.
PoweredByRice

1
O que significa manter o estado? O que é estado?
Kyle Delaney

2
@KyleDelaney: Simplesmente 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.
Xaqron 18/05

65

Classe estática: -

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

  2. Carregado automaticamente pelo CLR (Common Language Runtime) do .NET Framework quando o programa ou espaço para nome que contém a classe é carregado.

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

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

  5. Não podemos herdar a classe Static para outra classe Static em C #.

  6. Uma classe com todos os métodos estáticos.

  7. Melhor desempenho (métodos estáticos são ligados em tempo de compilação)

Singleton: -

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

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

  3. A classe Singleton pode ter construtor.

  4. Você pode criar o objeto da classe singleton e passá-lo ao método

  5. A classe Singleton não diz nenhuma restrição de herança.

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

  7. Métodos podem ser substituídos.

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

  9. Nós podemos implementar interface (classe estática não pode implementar interface).


13
Classes estáticas têm construtores: msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
Tomer Arazy

2
Sim, estático pode ter um construtor interno para essa classe. Isso é chamado quando qualquer método estático na classe é chamado.
rahulmr

Para singleton em tempo de compilação, ele é armazenado na memória HEAP, mas se for instanciado uma vez, será armazenado em STACK?
Luminous_Dev

@Luminous_Dev No. Qualquer instância singleton é uma instância de objeto no final do dia. Ele será armazenado na pilha sem dúvida.
RBT 23/01

1
@rahulmr Distinção importante: o construtor também é chamado antes da criação da primeira instância (somente AKA).
CoolOppo

53

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.


1
polimorfismo não entra em jogo com singletons de todo

32
Então você pensa. Eu penso diferente. ;) Por exemplo, imagine uma fábrica de singleton que retorna uma interface. Você sabe que está recebendo um ISingleton (e é o mesmo para sempre), mas não necessariamente qual implementação.
187 Morendil

A classe estática aninhada também pode ter métodos de instância, não se restringindo a ter apenas métodos estáticos. Codifique e você pode ver.
Nanosoft 9/16

Em linguagens com um modelo de objeto melhor (por exemplo, Ruby), as classes também são objetos. O aspecto "puramente processual" de uma classe estática é uma restrição arbitrária imposta pela linguagem.
Max

36

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:

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

39
Não é realmente um padrão único, parece mais fábrica para mim.
vava

10
Na verdade, a diferença fundamental entre os dois é que o Singleton "armazenará" em cache seu único objeto e continuará retornando (uma referência a) o mesmo. O padrão de fábrica criará novas instâncias.
místico

12
Então é proxy-singleton :)
vava

3
Hmm, conheço essa variedade do Singleton como MonoState.
Huppie 16/08/09

exemplo é padrão de fábrica
Rajavel D 13/08/14

26

Para expandir a resposta de Jon Skeet

A grande diferença entre um singleton e vários métodos estáticos é que os singletons podem implementar interfaces (ou derivar de classes base úteis, embora isso seja menos IME comum), para que você possa passar pelo singleton como se fosse "apenas mais uma implementação".

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.


Eu não acho que você possa zombar diretamente de um singleton. Você não precisaria declarar uma interface que o singleton e a classe mock implementem?
Ellen Spertus

@espertus Por que você não pode zombar do seu singleton? Exemplo usando mockito MySingleton mockOfMySingleton = mock(MySingleton.class).
Mike Rylander

você está certo, você pode zombar com ferramentas como mockito que usam reflexão. Eu quis dizer que você não pode zombar diretamente subclassificando-o e substituindo seus métodos.
Ellen Spertus

@espertus Por que não? Quando você instancia o objeto que está testando, pode substituir a implementação da subclasse do seu singleton onde quer que você usasse o original. Ex:new ClazzToTest(mockSingleton);
Mike Rylander

Eu não usei o Mockito, mas como você pode subclassificar uma classe que possui um construtor privado, o que é o caso de singletons, exceto usando reflexão? Discussões relacionadas: stackoverflow.com/questions/2302179/mocking-a-singleton-class stackoverflow.com/questions/15939023/…
Ellen Spertus

23

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 classe com todos os métodos estáticos .
  • melhor desempenho (métodos estáticos são ligados em tempo de compilação)
  • 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 )

    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");
        }
    }
    

Singleton

Em resumo, eu usaria apenas classes estáticas para armazenar métodos util e usar Singleton para todo o resto.


Editar% s


4
Não sei sobre java, mas em .Net, seus dois últimos pontos estão incorretos. As classes estáticas podem fazer referência a propriedades e campos estáticos; portanto, eles são iguais. E eles são carregados preguiçosamente - o construtor estático é executado quando: 1) Uma instância da classe é criada. 2) Qualquer um dos membros estáticos da classe é referenciado. 1 não se aplica, o que deixa 2. Portanto, uma classe estática não é carregada até a primeira vez que é usada.
precisa saber é

1
Para a classe estática, embora você não possa substituir o método estático, você pode ocultar o método estático de seu pai.
Max Peng

se Animal animal = new Cat();então o animal.foo();que acontece?
Luminous_Dev

A classe estática @jmoreno não é carregada até o primeiro uso? Eu acredito que ele é armazenado na memória da pilha em tempo de compilação. E é acessado instantaneamente .. não é?
Luminous_Dev

@Luminous_Dev: pelo menos para .net, uma classe estática tem um construtor que é executado quando acessado pela primeira vez, portanto não é acessível instantaneamente. O construtor estático poderia, em teoria, levar uma quantidade ilimitada de tempo. Onde (ou qualquer outra classe está armazenada) é um detalhe de implementação, que não é realmente relevante para esta questão.
jmoreno

22

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.


19

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.


15
Sim, todo mundo parece ignorar o fato de que uma classe com métodos estáticos também pode ter campos estáticos privados que ainda podem ser usados ​​para manter o estado (e expor alguns deles ao código do cliente através de setters / getters estáticos públicos).
user289463

17

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 SomeClassespera que uma instância de ILoggerimplementação seja passada para seu construtor.

A classe 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();
    }
}

13

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.


11

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.


A classe estática pode ser muito instanciada em java. Leia docs.oracle.com/javase/tutorial/java/javaOO/nested.html. Consulte também a minha resposta stackoverflow.com/a/37114702/1406510
Nanosoft

8

As principais diferenças são:

  • Singleton tem uma instância / objeto enquanto classe estática é um monte de métodos estáticos
  • Singleton pode ser estendido, por exemplo, através de uma interface, enquanto a classe estática não pode ser.
  • O Singleton pode ser herdado, o que suporta os princípios de abertura / fechamento nos princípios do SOLID, por outro lado, a classe estática não pode ser herdada e precisamos fazer alterações por si só.
  • O objeto Singleton pode ser passado para métodos, enquanto a classe estática, pois não possui instância, não pode ser passada como parâmetros

7

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:

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 de 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;
    }

classe 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 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.


1
Agora isso não é seguro para threads e geralmente desagradável em termos de como você acessa a implementação da interface. Claro, ter uma interface é bom para testabilidade - mas então por que se preocupar com um singleton? Apenas evite ter um singleton; tenha uma classe implementando-a para fins de produção, uma implementação para fins de teste e injete a instância correta, dependendo do que você estiver fazendo. Não é necessário acoplar o singleton aos seus interlocutores.
Jon Skeet

Obrigado pelo feedback. é muito simples torná-lo seguro. Além disso, eu uso singleton para fins de armazenamento em cache.
Amir Bareket

1
Sim, embora com sobrecarga inútil. Novamente, é mais simples não usar um singleton.
Jon Skeet

6

Estou de acordo com esta definição:

A palavra " único " significa um único objeto ao longo do ciclo de vida do aplicativo, portanto, o escopo está no nível do aplicativo.

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

Além disso, ambos devem ser implementados para serem seguros para threads.

Você pode encontrar outras diferenças interessantes sobre: Padrão Singleton versus classe estática


5

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.


4

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.


4

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ê ..


3
  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 lazyloading e implementação de interface)

A classe estática aninhada pode implementar muito a interface em java. Seu segundo ponto é errado.
Nanosoft 9/16

3

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.


3

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.


3

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

Cuidando dos Negócios

Lembre-se, uma das regras OO mais importantes é que um objeto é responsável por si mesmo. Isso significa que os problemas relacionados ao ciclo de vida de uma classe devem ser tratados na classe, não delegados a construções de linguagem como estática e assim por diante.

do livro Processo de Pensamento Objetivo-Orientado 4th Ed.


Eu discordaria, pois isso realmente acrescenta uma responsabilidade à classe, o que (supondo que faça alguma coisa) significa que agora viola o Princípio de Responsabilidade Única.
ssmith 16/04

3

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

  1. Classe estática não é realmente classe canônica - é um espaço para nome com funções e variáveis
  2. Usar classe estática não é uma boa prática devido à quebra de princípios de programação orientada a objetos
  3. A classe estática não pode ser passada como parâmetro para outros
  4. A classe estática não é adequada para inicialização "lenta"
  5. A inicialização e o uso da classe estática sempre são rastreados
  6. Implementar o gerenciamento de threads é difícil

Eu escová-lo para Inglês gramática, mas caso contrário, é uma leitura interessante :)
Noctis

3
  1. Podemos criar o objeto da classe singleton e passá-lo ao método

  2. A classe Singleton não tem nenhuma restrição de herança.

  3. Não podemos descartar os objetos de uma classe estática, mas podemos singleton.


Qual é a utilidade de passar um singleton para um método se sempre houver apenas um e esse sempre tiver uma referência estática?
Aaron Franke

3

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

  • É mais fácil escrever teste de unidade para singleton do que classe estática, porque você pode passar objetos simulados sempre que se espera singleton.

Vantagens da classe estática

  • A classe estática fornece melhor desempenho que o singleton, porque os métodos estáticos são vinculados no tempo de compilação.

Existem várias realizações do padrão singleton, cada uma com vantagens e desvantagens.

  • Ansioso de carregamento ansioso
  • Singleton de bloqueio verificado duas vezes
  • Idioma do detentor de inicialização sob demanda
  • O singleton baseado em enum

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


2

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.


1
Então, se o aplicativo sair, o Singleton ainda permanecerá na memória?
Nanosoft

Eu acho que você quer dizer quando o seu thread atual sai, não o aplicativo, certo? Se o aplicativo sair, não há como outro thread usar nada dele.
Tom Brito

2

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 :)


Qual é o sentido de passar um singleton como parâmetro, pois ele sempre tem uma referência estática na classe?
Aaron Franke
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.