Pergunta

O singleton padrão é um membro totalmente integralizado da GoF 's padrões reservar , mas ultimamente parece bastante órfãs pelo mundo do desenvolvedor. Eu ainda uso um monte de singletons, especialmente para href="https://en.wikipedia.org/wiki/Factory_method_pattern" classes de fábrica , e quando você tem que ser um mordeu cuidado com multithreading problemas (como qualquer classe na verdade), não vejo por que eles são tão terrível.

Stack Overflow especialmente parece supor que todos concordam que Singletons são maus. Por quê?

Por favor, apoiem suas respostas com " fatos, referências, ou conhecimentos específicos "

Foi útil?

Solução

parafraseado de Brian Button:

  1. Eles geralmente são usados ??como uma instância global, por que isso é tão ruim? Porque você esconder as dependências de sua aplicação em seu código, em vez de expô-los através das interfaces. Fazer algo global para evitar passá-lo ao redor é um cheiro de código .

  2. Eles violam a único princípio da responsabilidade : em virtude do fato de que eles controlam sua própria criação e ciclo de vida.

  3. Eles inerentemente causa código para ser firmemente juntamente . Isso faz com que fingir-los em teste bastante difícil em muitos casos.

  4. Eles carregam estado ao redor para a vida útil do aplicativo. Outro sucesso do teste, pois você pode acabar com uma situação onde os testes precisam ser solicitados que é um grande não não para testes de unidade. Por quê? Como cada unidade de teste deve ser independente da outra.

Outras dicas

Singletons resolver um (e apenas um) problema.

Resource Contenção.

Se você tem algum recurso que

( 1 ) pode ter apenas um único exemplo, e

( 2 ) que você precisa para gerenciar essa única instância,

você precisa de um Singleton .

Não há muitos exemplos. Um arquivo de log é um dos grandes. Você não quer simplesmente abandonar um único arquivo de log. Você quer flush, sincronização e fechá-lo corretamente. Este é um exemplo de um único recurso compartilhado que tem de ser gerido.

É raro que você precisa de um singleton. A razão que eles são ruins é que eles se sentem como um global e eles estão totalmente integralizadas membro da GoF design Patterns livro.

Quando você acha que precisa de um global, provavelmente você está cometendo um erro terrível design.

Alguns esnobes codificação olhar para baixo sobre eles como apenas um mundial glorificado. Da mesma forma que muitas pessoas odeiam o Goto declaração há outros que odeiam a idéia de nunca usar um Global . Tenho visto vários desenvolvedores ir a extremos para evitar uma Global , porque eles considerou usar um como uma admissão de fracasso. Estranho, mas verdadeiro.

Na prática, a Singleton padrão é apenas uma técnica de programação que é uma parte útil do seu kit de ferramentas de conceitos. De vez em quando você pode achar que é a solução ideal e para usá-lo. Mas usá-lo apenas para que você pode se gabar sobre como usar um padrão de design é tão estúpido quanto recusando-se a nunca usá-lo porque ele é apenas um Global .

Misko Hevery, do Google, tem alguns artigos interessantes sobre exatamente este tema ...

Singletons são patológicas Mentirosos tem uma unidade testando exemplo que ilustra como singletons pode torná-lo difícil de descobrir cadeias de dependência e iniciar ou testar um aplicativo. É um exemplo bastante extremo de abuso, mas o ponto que ele faz ainda é válido:

Singletons são nada mais do que o estado global. estado global torna tão seus objetos podem secretamente se apossar de coisas que não são declaradas em suas APIs, e, como resultado, Singletons fazer suas APIs em mentirosos patológicos.

onde foram todos os Singletons ido faz o ponto que a injeção de dependência tornou mais fácil para obter instâncias para construtores que necessitam deles, o que alivia a necessidade subjacente por trás do mau, Singletons globais denunciou no primeiro artigo.

Eu acho que a confusão é causada pelo fato de que as pessoas não sabem a aplicação real do padrão Singleton. Eu não posso forçar este bastante. Singleton é não um padrão para globals envoltório. padrão Singleton só deve ser usado para garantia de que uma e apenas uma instância de uma determinada classe existe durante a execução.

As pessoas pensam Singleton é mau, porque eles estão usando-o para globals. É por causa desta confusão que Singleton é desprezada. Por favor, não confunda Singletons e globals. Se utilizados para os fins a que se destina, você vai ganhar benefícios extremos do padrão Singleton.

Uma vez coisa ruim sobre singletons é que você não pode estender-los muito facilmente. Você basicamente tem que construir em algum tipo de decorador padrão ou alguma coisa se você quiser mudar a sua comportamento. Além disso, se um dia você quiser ter várias maneiras de fazer isso uma coisa, ele pode ser bastante doloroso para mudança, dependendo de como você definir o seu código.

Uma coisa a nota, se você usar singletons, tentar passá-los para quem precisa deles, em vez de tê-los acessá-lo diretamente ... Caso contrário, se você optar por ter várias maneiras de fazer a coisa que singleton faz, ele vai ser bastante difícil mudar como cada classe incorpora uma dependência se acessa o singleton diretamente.

Então, basicamente:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

em vez de:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

Eu acredito que este tipo de padrão é chamado injeção de dependência e é geralmente considerado uma coisa boa.

Como qualquer padrão embora ... Pense nisso e considerar se seu uso em todas as situações é inadequada ou não ... As regras são feitas para serem quebradas geralmente, e padrões não devem ser aplicadas quer queira quer não, sem pensamento.

O padrão Singleton não é um problema em si. O problema é que o padrão é frequentemente usado por pessoas que desenvolvem software com ferramentas orientadas a objetos, sem ter uma sólida compreensão de conceitos de OO. Quando singletons são introduzidos neste contexto eles tendem a crescer em classes incontroláveis ??que contêm métodos auxiliares para cada uso pouco.

Singletons também são um problema a partir de uma perspectiva de teste. Eles tendem a fazer isoladas unidade-testes difícil de escrever. Inversão de controle (IOC) e injeção de dependência são padrões significou para superar este problema de uma maneira orientada a objetos que se presta a testes de unidade .

Em um lixo coletado singletons ambiente pode rapidamente tornar-se um problema que diz respeito à gerenciamento de memória.

Há também o cenário multi-threaded, onde singletons pode se tornar um gargalo, bem como um problema de sincronização.

A Singleton será implementado utilizando um método estático. Os métodos estáticos são evitados por pessoas que fazem o teste de unidade, porque eles não podem ser ridicularizado ou apagou. A maioria das pessoas neste site são grandes defensores da testes de unidade. A convenção geral mais aceita para evitá-los é usando a inversão de padrão de controle .

Singletons também são ruins quando se trata de agrupamento . Porque, então, você não tem "exatamente um singleton" em sua aplicação mais.

Considere a seguinte situação: Como um desenvolvedor, você tem que criar um aplicativo web que acessa um banco de dados. Para garantir que as chamadas banco de dados simultâneas não entrem em conflito uns aos outros, você cria um fio-save SingletonDao:

public class SingletonDao {
    // songleton's static variable and getInstance() method etc. omitted
    public void writeXYZ(...){
        synchronized(...){
            // some database writing operations...
        }
    }
}

Então, você tem certeza de que apenas um singleton em sua aplicação existe e todo banco de dados passar por este primeiro e único SingletonDao. Seu ambiente de produção agora se parece com isso: Single Singleton

Tudo está bem até agora.

Agora, considere que você deseja configurar várias instâncias de sua aplicação web em um cluster. Agora, de repente você tem algo como isto:

Muitas singletons

Isso soa estranho, mas agora você tem muitos singletons em sua aplicação . E isso é exatamente o que um singleton não é suposto ser: Ter muitos objetos do mesmo. Isto é especialmente ruim se você, como mostrado neste exemplo, quiser fazer chamadas sincronizados com um banco de dados.

Claro que isto é um exemplo de um mau uso de um singleton. Mas a mensagem deste exemplo é:. Você não pode confiar que há exatamente uma instância de um singleton em sua aplicação - especialmente quando se trata de agrupamento

  1. É facilmente (ab) usado como uma variável global.
  2. classes que dependem únicos são relativamente difíceis de teste de unidade em isolamento.

Monopoly é o diabo e singletons com somente leitura não-estado mutável / são o problema 'real' ...

Depois de ler Singletons são patológicos Mentirosos como sugerido na resposta de jason me deparei com este pequeno petisco que fornece o melhor exemplo apresentado de como singletons são muitas vezes mal utilizado.

Global é ruim porque:

  • a. Ela provoca conflito namespace
  • b. Ele expõe o estado de uma forma injustificada

Quando se trata de Singletons

  • a. A maneira OO explícita de chamá-los, impede que os conflitos, por isso apontar a. não é uma questão
  • b. Singletons sem estado são (como fábricas) não é um problema. Singletons com o estado pode voltar a cair em duas categorias, aqueles que são imutáveis ??ou escrever uma vez e ler muitas (arquivos config / propriedade). Estes não são ruins. Mutáveis ??Singletons, que são tipo de titulares de referência são os únicos que você está falando.

Na última declaração que ele está se referindo ao conceito do blog de 'singletons são mentirosos'.

Como isso se aplica ao monopólio?

Para iniciar um jogo do monopólio, em primeiro lugar:

  • nós estabelecemos as regras primeiro, para que todo mundo está na mesma página
  • todo mundo é dado um início igual no início do jogo
  • apenas um conjunto de regras é apresentado a confusão evitar
  • as regras não estão autorizados a mudança ao longo do jogo

Agora, para quem não tem realmente monopólio jogado , estas normas são ideais na melhor das hipóteses. A derrota no monopólio é difícil de engolir porque, o monopólio é sobre dinheiro, se você perder você tem que observar cuidadosamente o resto dos jogadores terminar o jogo, e as perdas são geralmente rápida e esmagamento. Assim, as regras geralmente são torcidos em algum momento de servir o interesse de alguns dos jogadores em detrimento dos outros.

Então você é monopólio de jogo com amigos Bob, Joe e Ed. Você está construindo rapidamente seu império e consumindo quota de mercado a uma taxa exponencial. Seus adversários estão enfraquecendo e você começa a sangue cheiro (figurativamente). Seu amigo Bob colocar todo o seu dinheiro em gridlocking quantas propriedades de baixo valor possível, mas o seu não está recebendo um alto retorno sobre o investimento do jeito que ele esperava. Bob, como um golpe de má sorte, as terras em seu calçadão e é retirado do jogo.

Agora o jogo vai desde amigáveis ??dice-rolando para um negócio sério. Bob foi feito o exemplo de fracasso e Joe e Ed não quer acabar como 'o cara'. Assim, sendo o jogador que leva você, de repente, tornar-se o inimigo. Joe e Ed começar a praticar trades-under-tabela de, injeções de dinheiro por trás das costas, subvalorizadas de troca de casa e, geralmente, qualquer coisa para enfraquecê-lo como um jogador até que um deles sobe ao topo.

Então, em vez de um deles ganhar, o processo começa tudo de novo. De repente, um conjunto finito de regras torna-se um alvo em movimento e os degenerados jogo para o tipo de interações sociais que compõem a base de cada reality show avaliado de alta desde sobrevivente. Por que, porque as regras estão mudando e não há consenso sobre como / por que / o que é suposto representar, e mais importante, não há uma pessoa tomar as decisões. Cada jogador no jogo, naquele momento, está fazendo seus / suas próprias regras e ensues caos até que dois dos jogadores está cansado demais para manter a farsa e lentamente desistir.

Assim, se um livro de regras para um jogo representado com precisão um singleton, o livro de regras monopólio seria um exemplo de abuso.

Como isso se aplica à programação?

Além de tudo o óbvio thread-segurança e problemas de sincronização that singletons mutáveis ??presente ... Se você tem um conjunto de dados, que é capaz de ser lido / manipulado por várias fontes diferentes ao mesmo tempo e existe durante a vida útil da execução da aplicação, é provavelmente um bom momento para passo para trás e perguntar "am I usando o tipo certo de estrutura de dados aqui".

Pessoalmente, tenho visto um programador abusar de um singleton usando-o como uma espécie de loja de banco de dados torcida cruz-thread em um aplicativo. Tendo trabalhado no código diretamente, eu posso atestar que era um lento (por causa de todas as fechaduras de rosca necessários para torná-lo thread-safe) e um pesadelo para trabalhar (devido à natureza imprevisível / intermitente de erros de sincronização) e quase impossível de teste sob condições de 'produção'. Claro, um sistema poderia ter sido desenvolvido usando polling / sinalização para superar alguns dos problemas de desempenho, mas que não iria resolver os problemas com o teste e, por que se preocupar quando um banco de dados 'real' já pode realizar a mesma funcionalidade de forma muito mais robusta / forma escalável.

A Singleton é única uma opção se você precisa que um singleton fornece. Uma escrita e um read-only instância de um objeto. Essa mesma regra deve cascata para as propriedades do objeto / membros também.

Singleton não é sobre a única instância!

Ao contrário de outras respostas que eu não quero falar sobre o que está errado com Singletons mas para mostrar-lhe o quão poderoso e terrível que eles estão certos quando usado!

  • Problema : Singleton pode ser um desafio em ambiente multi-threading
    Solução :. Use um único processo de inicialização de rosca para inicializar todas as dependências do seu Singleton
  • Problema :. É difícil singletons simulados
    Solução : padrão Use método Fábrica para zombando
    MyModel myModel = Factory.inject(MyModel.class); Você pode mapear MyModel a classe TestMyModel que herda-lo, em todos os lugares quando MyModel será injetado você receberá TestMyModel instread.
  • Problema :. Singletons podem causar alho-poró memória como eles nunca eliminados
    Solução : Bem, descartá-los! Implementar uma chamada de retorno em seu aplicativo para descartar adequadamente uma singletons, você deve remover todos os dados ligados a eles e, finalmente: removê-los da fábrica.

Como afirmei no singleton título não está prestes única instância.

  • Singletons melhora a legibilidade :. Você pode olhar para a sua classe e ver o que Singleton-lo injetado para descobrir o que é que é dependências
  • Singletons melhora manutenção : Uma vez que você removeu uma dependência de uma classe que você acabou de excluir alguns injeção Singleton, você não precisa ir e editar uma grande ligação de outras classes que apenas movido sua dependência em torno de (Este é o código mau cheiro para mim @ Jim Burger )
  • Singletons melhora a memória e desempenho : Quando alguma coisa acontece em sua aplicação, e leva uma longa cadeia de chamadas de retorno para entregar, você está desperdiçando memória e desempenho, usando Singleton você está cortando o meio homem, e melhorar o seu desempenho e uso de memória (evitando desnecessárias variáveis ??locais alocações).

A minha resposta sobre como Singletons são ruins é sempre, "eles são difíceis de fazer o certo". Muitos dos componentes fundamentais de línguas são singletons (classes, funções, namespaces e mesmo os operadores), assim como os componentes em outros aspectos da computação (localhost, rota padrão, sistema de arquivos virtual, etc.), e não é por acaso. Enquanto eles causam problemas e frustrações ao longo do tempo, eles também podem fazer um monte de coisas funcionam muito melhor.

Os dois maiores ups parafuso que vejo são:. Tratando-o como um mundial e não definir o fechamento Singleton

Todos falam sobre Singleton de como globais, porque eles são basicamente. No entanto, muito (infelizmente, não todos) da maldade em um global não vem intrinsecamente de ser global, mas como você usá-lo. O mesmo vale para Singletons. Na verdade, tanto mais que "instância única" realmente não precisa média "globalmente acessível". É mais um subproduto natural, e dado tudo de ruim que sabemos vem dele, não devemos estar em tal pressa a explorar a acessibilidade global. Uma vez que os programadores ver um Singleton eles parecem sempre acessá-lo diretamente através do seu método de instância. Em vez disso, você deve navegar para ele apenas como faria com qualquer outro objeto. A maioria dos códigos não deve mesmo estar ciente de que está lidando com um Singleton (acoplamento fraco, certo?). Se apenas um pequeno pedaço de código acessa o objeto como se fosse um global, uma grande quantidade de dano é desfeita. Eu recomendo aplicá-la, restringindo o acesso à função exemplo.

O contexto Singleton também é muito importante. A característica definidora de um Singleton é que não há "apenas um", mas a verdade é que é "apenas um" dentro de algum tipo de contexto / namespace. Eles são geralmente um de: um por thread, processo, endereço IP ou cluster, mas também pode ser uma por processador, máquina, namespace idioma / carregador de classe / whatever, sub-rede, Internet, etc

.

O outro, menos comum, erro é ignorar o estilo de vida Singleton. Só porque há apenas um não significa um Singleton é algum onipotente "sempre foi e sempre será", nem é geralmente desejáveis ??(objetos sem início e de fim violar todos os tipos de hipóteses úteis no código, e só deve ser empregada na mais desesperada das circunstâncias.

Se você evitar esses erros, Singletons pode ainda ser um PITA, mordeu ele está pronto para ver um monte dos piores problemas são significativamente mitigados. Imagine um Java Singleton, que é explicitamente definido como uma vez por carregador de classe (o que significa que precisa de uma política de segurança do thread), com métodos de criação e destruição definidos e um ciclo de vida que determina quando e como eles são chamados, e cujo método de "instância" tem pacote de proteção por isso é geralmente acessado através de outros objetos, não globais. Ainda uma fonte potencial de problemas, mas certamente muito menos problemas.

Infelizmente, em vez de ensinar bons exemplos de como fazer Singletons. Nós ensinamos maus exemplos, vamos programadores fugir usá-los por um tempo, e depois dizer-lhes que eles são um padrão de design ruim.

Veja Wikipedia Singleton_pattern

Também é considerado um anti-padrão por algumas pessoas, que acham que ele é excessivamente utilizado, a introdução de limitações desnecessárias em situações onde uma única instância de uma classe não é realmente necessário. [1] [2] [3] [ 4]

Referências (somente referências relevantes do artigo)

  1. ^ Alex Miller. Padrões Eu odeio # 1: Singleton, julho de 2007
  2. ^ Scott Densmore. Por singletons são maus , maio de 2004
  3. ^ Steve Yegge. Singletons considerado estúpido , setembro de 2004
  4. ^ J.B. Rainsberger, IBM. Use seus singletons sabiamente , julho de 2001

Não é que os próprios singletons são ruins, mas o padrão de design GoF é. O argumento só é realmente que é válido é que o padrão de design GoF não se presta no que diz respeito aos testes, especialmente se os testes são executados em paralelo.

Usando uma única instância de uma classe é uma construção válida contanto que você aplicar os seguintes meios de código:

  1. Certifique-se a classe que será usada como um singleton implementa uma interface. Isso permite que topos ou simulações a serem implementadas usando a mesma interface

  2. Certifique-se de que o Singleton é thread-safe. Isso é um dado.

  3. O singleton deve ser simples na natureza e não excessivamente complicado.

  4. Durante o tempo de execução da sua aplicação, onde singletons precisa ser passado para um determinado objeto, use uma fábrica de classes que constrói o objeto e ter a fábrica de classe passar a instância singleton da classe que precisa.

  5. Durante o teste e para garantir um comportamento determinista, criar a única classe como exemplo separado, como seja a classe propriamente dita ou a topo / simulada que implementa o seu comportamento e passá-lo como é a classe que o exija. Não use o fator de classe que cria o objeto sob teste que precisa do singleton durante o teste, uma vez que vai passar a instância global único dele, que derrota o propósito.

Nós usamos Singletons em nossas soluções com uma grande quantidade de sucesso que são testáveis ??assegurando um comportamento determinístico em fluxos de execução de teste paralelas.

Vince Huston tem esses critérios, que parecem razoável para mim:

Singleton deve ser considerado apenas se todos os três dos seguintes critérios são satisfeitos:

  • A propriedade da única instância não pode ser razoavelmente atribuído
  • preguiçoso inicialização é desejável
  • O acesso global é Salvo disposição em contrário

Se a propriedade da única instância, quando e como inicialização ocorre, e acesso global não são problemas, Singleton não é suficientemente interessante.

Eu gostaria de abordar os 4 pontos na resposta aceita, espero que alguém pode explicar por que eu estou errado.

  1. Por que está escondendo dependências em seu código ruim? Já existem dezenas de dependências escondidas (chamadas de tempo de execução C, chamadas de API do sistema operacional, chamadas de função globais), e dependências únicas são fáceis de encontrar (procure por exemplo ()).

    "Fazer algo global para evitar passá-lo ao redor é um cheiro de código." Por que não está passando algo ao redor para evitar tornando-se um singleton um cheiro de código?

    Se você está passando um objeto através de 10 funções em uma pilha de chamadas apenas para evitar um singleton, é que tão grande?

  2. Responsabilidade único princípio: Eu acho que isso é um pouco vago e depende de sua definição de responsabilidade. Uma questão relevante seria, por que adicionar este específica "responsabilidade" para uma questão de classe?

  3. Por que passando um objeto para um make classe mais intimamente ligado do que usar esse objeto como um solteirão de dentro da classe?

  4. Por que alterar o tempo que o estado dura? Singletons podem ser criados ou destruídos manualmente, de modo que o controle ainda está lá, e você pode fazer o tempo de vida o mesmo que a vida de um objeto não-singleton seria.

Quanto testes de unidade:

  • nem todas as classes precisam ser unidade testado
  • Não todas as classes que precisam ser unidade testado necessidade de mudar o implementação do singleton
  • se não precisa ser unidade testada e é necessário alterar a implementação, é fácil mudar uma classe de usando um Singleton para ter o Singleton passado para ele via dependência injeção.

Eu não vou comentar sobre o argumento bem / mal, mas eu não tê-los usado desde Spring veio junto. Usando injeção de dependência tem praticamente removido os meus requisitos para solteirão, servicelocators e fábricas. Acho isso muito mais produtivo e ambiente limpo, pelo menos para o tipo de trabalho que faço (aplicações web baseadas em Java).

Não há nada de intrinsecamente errado com o padrão, assumindo que ele está sendo usado por algum aspecto de seu modelo que é verdadeiramente único.

Eu acredito que a reação é devido ao seu uso excessivo, que, por sua vez, é devido ao fato de que é o padrão mais fácil de compreender e aplicar.

Singletons são ruins de um ponto purista de vista.

Do ponto de vista prático, um singleton é um trade-off tempo desenvolvendo vs complexidade .

Se você sabe que a sua aplicação não vai mudar isso quanto eles são bastante OK para ir com ele. Só sei que você pode precisar refatorar as coisas se suas exigências mudar de forma inesperada (o que é bastante OK na maioria dos casos).

Singletons vezes também complicar unidade de teste .

Singleton é um padrão e pode ser usado ou abusado assim como qualquer outra ferramenta.

A parte ruim de um singleton é geralmente o usuário (ou devo dizer do uso inadequado de um Singleton para que as coisas não se destina a fazer). O maior agressor está usando um singleton como uma variável global falso.

Quando você escreve código usando singletons, digamos, um registador ou uma conexão de banco de dados, e depois você descobrir que você precisa mais de um log ou mais de um banco de dados, você está em apuros.

Singletons tornam muito difícil para mover a partir deles para objetos regulares.

Além disso, é muito fácil escrever um singleton-non-thread-safe.

Ao invés de usar singletons, você deve passar todos os utilitários necessários objetos de função para função. Isso pode ser simplificado se você quebrar todos eles em um objeto auxiliar, como este:

void some_class::some_function(parameters, service_provider& srv)
{
    srv.get<error_logger>().log("Hi there!");
    this->another_function(some_other_parameters, srv);
}

Os problemas com singletons é a questão do aumento da abrangência e, portanto acoplamento . Não há como negar que há alguns de situações onde você fazer necessitem de acesso a uma única instância, e isso pode ser feito de outras maneiras.

I agora preferem projetar em torno de uma inversão de controle recipiente (COI) e permitir que o do vidas para ser controlado pelo recipiente. Isto dá-lhe o benefício das classes que dependem da instância não ter conhecimento do fato de que há uma única instância. O tempo de vida do singleton pode ser alterado no futuro. Uma vez que tal exemplo que encontrei recentemente foi um ajuste fácil de único segmento de multi-threaded.

FWIW, se um PIA quando você tenta teste de unidade que, em seguida, ele vai PIA quando você tenta depuração, correção de bug ou melhorá-lo.

artigo recente sobre este assunto por Chris Reath em Codificação Sem Comentários .

Nota: Codificação Sem Comentários não é mais válido. No entanto, o artigo que está sendo ligado a foi clonado por outro usuário.

http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx

Aqui está mais uma coisa sobre singletons que ninguém disse ainda.

Na maioria dos casos "singletonity" é um detalhe de implementação para alguma classe ao invés de característica de sua interface. Inversão de Controle Container pode esconder essa característica de usuários de classe; você só precisa marcar a sua classe como um Singleton (com anotação @Singleton em Java, por exemplo) e é isso; IOCC fará o resto. Você não precisa fornecer acesso global à instância singleton porque o acesso já é gerido por IOCC. Assim, não há nada de errado com IoC Singletons.

GoF Singletons em frente ao IoC Singletons são supostamente para expor "singletonity" na interface através do método getInstance (), e assim que eles sofrem de tudo dito acima.

Singletons não são ruins. É somente mau quando você faz algo exclusivo global que não é exclusivo global.

No entanto, existem "serviços âmbito de aplicação" (pensar em um sistema de mensagens que faz com que os componentes interagem) - isto exige um singleton, um "MessageQueue" - classe que tem um método "SendMessage (...)" <. / p>

Você pode, em seguida, faça o seguinte em todo o lugar:

MessageQueue.Current.SendMessage (novo MailArrivedMessage (...));

E, claro, fazer:

MessageQueue.Current.RegisterReceiver (this);

em classes que implementam IMessageReceiver.

Muitas pessoas colocam objetos que não são thread-safe em um padrão Singleton. Eu vi exemplos de um DataContext ( LINQ to SQL ) feito em um padrão Singleton, apesar do fato de que o DataContext não é thread-safe e é puramente um objeto de unidade de trabalho.

Porque eles são basicamente orientada a objetos variáveis ??globais, normalmente você pode projetar suas classes de tal forma para que você não precisa deles.

Um padrão emerge quando várias pessoas (ou equipes) chega a soluções semelhantes ou idênticos. Um monte de pessoas ainda usam singletons em sua forma original ou usando modelos de fábrica (boa discussão em Design ++ Modern C do Alexandrescu). Simultaneidade e dificuldade em gerir o tempo de vida do objeto são os principais obstáculos, com o ex-facilmente gerenciadas como você sugere.

Como todas as escolhas, Singleton tem seu quinhão de altos e baixos. Eu acho que eles podem ser usados ??com moderação, especialmente para objetos que sobrevivem ao tempo de vida do aplicativo. O fato de que eles se assemelham (e provavelmente é) globals presumivelmente detonar os puristas.

Em primeiro lugar uma classe e seus colaboradores em primeiro lugar deve realizar sua finalidade ao invés de focar deoendents. gerenciamento de ciclo de vida (quando instâncias são creared snd quando eles saem de escopo) não deve ser parte da responsabilidade cladses. A melhor prática aceita para isso é ofício ou configure um novo componente para gerenciar dependências usando injeção de dependência.

Muitas vezes software fica mais complicado faz sentido ter várias instâncias independentes da classe "singleton" com estado diferente. Cometer código para simplesmente pegar o singleton está errado em tais casos. Usando Singleton.getInstance () pode ser ok para pequenos sistemas simples, mas ele não funciona / escala quando um pode precisar de uma instância diferente da mesma classe.

Nenhuma classe deve ser pensado como um singleton mas sim que deve ser uma aplicação dela é o uso ou como ele é usado para dependentes configurar. Para um rápido e desagradável isso não importa- apenas luke hardcoding caminhos de arquivo digamos não importa, mas para aplicações maiores tais dependências precisam ser levadas para fora e gerido de maneira usando DI mais apropriado.

Os problemas que causa singleton em testes é um sintoma de sua codificado uso único caso / meio ambiente. O conjunto de testes e os muitos testes são cada algo individual e separado que não é compatível com a codificar um singleton.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top