Este artigo é voltado para aqueles que encontraram pela primeira vez o conceito de padrões, ouviram falar de
Singleton
'e, ou de alguma forma o fizeram, mas ainda não entenderam nada. Bem-vindo! Os alunos JavaRush encontram padrões pela primeira vez no nível 15, quando inesperadamente o limite pede para “consertar” e implementar um padrão
Singleton
com uma implementação lenta. Os alunos que ouvem falar sobre isso pela primeira vez
Singleton
imediatamente têm um monte de perguntas: o que é um padrão, por que é necessário, que tipo de padrão é
Singleton
e, finalmente, que tipo de implementação preguiçosa é essa. Vamos começar a responder em ordem:
Afinal, o que é um padrão?
Para uma melhor compreensão, acho que vale a pena responder a essa pergunta da história. Entre os programadores estão quatro autores famosos: Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, que tiveram uma ideia interessante.
Eles notaram que, ao escrever programas, muitas vezes tinham que resolver aproximadamente os mesmos problemas e escrever códigos do mesmo tipo em estrutura. Portanto, eles decidiram descrever na forma de padrões padrões típicos que são frequentemente usados na programação orientada a objetos. O livro foi publicado em 1995 com o título
“Técnicas de Design Orientado a Objetos. Padrões de design" . O título do livro acabou sendo muito longo e ficou conhecido simplesmente como
O Livro da Gangue dos Quatro . Na primeira edição foram publicados 23 padrões, após os quais foram descobertas dezenas de outros. Então, respondendo à pergunta deste parágrafo,
“O que são padrões?” , vamos resumir em apenas algumas palavras:
Um padrão é uma solução padronizada para um problema comum. |
E
Singleton
este é apenas um desses padrões.
Por que precisamos de padrões (padrões de design)
Você pode programar sem conhecer padrões; você pode verificar isso simplesmente percebendo o fato de que no 15º nível do JavaRush você escreveu centenas de miniprogramas sem saber nada sobre sua existência. Isso sugere que um padrão é uma espécie de ferramenta, cuja presença distingue um mestre de um amador:
Os padrões descrevem como resolver corretamente um dos problemas típicos. Como resultado, conhecer os padrões economiza tempo. Uma analogia pode ser feita com algoritmos. Por exemplo, você pode criar seu próprio algoritmo de classificação
com blackjack e números e gastar muito tempo nele, ou pode usar um que já foi descrito há muito tempo e implementá-lo. O mesmo acontece com os padrões. Além disso, com o uso de padrões, o código fica mais padronizado, e ao utilizar os padrões certos, você terá menos chances de cometer erros, pois eles já foram previstos e eliminados neste padrão. Bem, além de tudo, o conhecimento dos padrões permite que os programadores se entendam melhor. Simplesmente dizer o nome do modelo é suficiente, em vez de tentar explicar aos seus colegas programadores o que você deseja que eles façam.
Então, para resumir, os padrões de design ajudam:
- não reinvente a roda, mas utilize soluções padronizadas;
- padronizar código;
- padronizar a terminologia;
|
Concluindo esta seção, notamos que toda a variedade de padrões pode ser simplificada em três grandes grupos:
Finalmente um padrão Singleton
Singleton
refere-se a
padrões generativos . Sua tradução literal é solitária. Este padrão garante que uma classe tenha apenas um objeto (uma instância da classe) e que um ponto de acesso global seja fornecido para esse objeto. Deve ficar claro na descrição que esse padrão deve ser usado em dois casos:
- quando não mais do que um objeto de qualquer classe deve ser criado em seu programa. Por exemplo, em um jogo de computador você tem uma classe “Personagem”, e essa classe deve ter apenas um objeto que descreva o próprio personagem.
- quando você precisa fornecer um ponto de acesso global para um objeto de classe. Em outras palavras, você precisa ter certeza de que o objeto é chamado de qualquer lugar do programa. E, infelizmente, para isso não basta simplesmente criar uma variável global, pois ela não é protegida contra gravação e qualquer pessoa pode alterar o valor desta variável e o ponto de acesso global ao objeto será perdido. Essas propriedades
Singleton
são necessárias, por exemplo, quando você tem um objeto de uma classe que funciona com um banco de dados e precisa que o banco de dados seja acessível a partir de diferentes partes do programa. E Singleton
garantirá que nenhum outro código substituiu a instância da classe criada anteriormente.
Estes dois problemas são resolvidos por
Singleton
: deve haver apenas um objeto no programa e deve haver acesso global a ele. No exemplo do nível 15, o limite pede para implementar este padrão para a seguinte tarefa (aqui está sua descrição):
Depois de ler atentamente a condição, fica claro por que exatamente
Singleton
(Single) é necessário aqui. Afinal, o programa pede para você criar um objeto de cada classe:
Sun
,
Moon
,
Earth
. E é lógico supor que cada classe do programa não deva criar mais do que um Sol/Lua/Terra, caso contrário será um absurdo, a menos, é claro, que você esteja escrevendo sua própria versão de Star Wars.
Recurso de implementação Singleton
Java em três etapas O comportamento singleton em Java não pode ser implementado usando um construtor regular porque o construtor sempre retorna um novo objeto. Portanto, todas as implementações de
Singleton
'a se resumem a ocultar o construtor e criar um método estático público que controlará a existência de um único objeto e “destruirá” todos os objetos recém-aparecidos. Se
Singleton
'a for chamado, ele deverá criar um novo objeto (se ainda não estiver no programa) ou retornar um que já tenha sido criado. Para fazer isso:
#1. – Você precisa adicionar um campo estático privado à classe que contém um único objeto:
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
}
#2. – Torne o construtor da classe (construtor padrão) privado (para que o acesso a ele seja fechado fora da classe, então ele não poderá retornar novos objetos):
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){}
}
#3 . – Declare um método de criação estático que será usado para obter o singleton:
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){}
public static LazyInitializedSingleton getInstance(){
if(instance == null){
instance = new LazyInitializedSingleton();
}
return instance;
}
}
O exemplo acima é um tanto desajeitado, porque simplesmente ocultamos o construtor e fornecemos nosso próprio método em vez do construtor padrão. Como este artigo tem como objetivo permitir que os alunos do JavaRush entrem em contato com esse padrão (e com os padrões em geral) pela primeira vez, os recursos de implementação de Singletons mais complexos não serão fornecidos aqui. Observamos apenas que dependendo da complexidade do programa, pode ser necessário um refinamento mais detalhado deste padrão. Por exemplo, em um ambiente multithread (veja o tópico Threads), vários threads diferentes podem chamar simultaneamente o método getter do Singleton, e o código descrito acima irá parar de funcionar, porque cada thread individual será capaz de criar múltiplas instâncias da classe de uma vez só. Portanto, ainda existem várias abordagens diferentes para criar singletons thread-safe corretos. Mas isso é outra história =)
E finalmente. O que é inicialização lenta que o limite pediu ?A inicialização lenta também é chamada de inicialização lenta. Esta é uma técnica de programação em que uma operação que consome muitos recursos (e a criação de um objeto é uma operação que exige muitos recursos) é executada sob demanda, e não antecipadamente. Que é basicamente o que acontece em nosso código
Singleton
'a. Ou seja, nosso objeto é criado no momento em que é acessado, e não antecipadamente. Não se deve presumir que o conceito de inicialização lenta esteja de alguma forma estritamente conectado com
Singleton
'om. A inicialização lenta também é usada em outros padrões de design generativos, por exemplo, em Proxy e Factory Method, mas isso é outra história =)
As seguintes fontes foram usadas na preparação do artigo:
- Práticas recomendadas do padrão de design Java Singleton com exemplos
- Padrões de design
- Singleton correto em Java
GO TO FULL VERSION