Análise de padrões de design de instância simples singleton
Prefácio
Hoje, darei a você um resumo abrangente do padrão de design mais usado no desenvolvimento do Android - Singleton.
Em relação à introdução aos padrões de design, você pode ler o que eu escrevi antes: 1 minuto para entender completamente "Padrões de design"
Índice
1. Introduzir
1.1 que problemas são resolvidos
Como mencionado anteriormente, o padrão de design = uma solução para um certo tipo de problema específico, então qual é o problema do padrão de singleton ?
Significado: singleton = uma instância;
Problema resolvido: reduza o acoplamento entre os objetos
Solução: Padrão Singleton, isto é, implementando que uma classe tem apenas um objeto instanciado e fornece um ponto de acesso global
1.2 Introdução à instância
Em seguida, uso uma instância para introduzir o padrão de singleton
Antecedentes: Xiaocheng tem uma fábrica de plásticos, mas há apenas um armazém dentro.
Objetivo: quero usar o código para implementar o gerenciamento de armazém
Práticas atuais: estabelecer armazéns e trabalhadores
Entre eles, a quantidade na classe do armazém = a quantidade de mercadorias; Os trabalhadores têm os métodos de manuseio Movein (int i) e Moveout (int i).
Problemas: Através do teste, verificou -se que toda vez que um trabalhador se move, um novo armazém será construído, ou seja, as mercadorias não são colocadas no mesmo armazém. O que está acontecendo? (Veja o código abaixo)
pacote scut.designmodel.singletonpattern; // Classe de armazém de classe Warehouse {private int Quantity = 100; public void setQuantity (int quantity) {this.quantity = Quantity; } public int getQuantity () {return Quantity; }} // caminhar portadora de classe humana {public storehouse mstorehouse; operadora pública (armazém de armazém) {mstorehouse = storehouse; } // movendo as mercadorias para o armazém vazio de void de armazém (int i) {mStorehouse.setquantity (mStorehouse.getQuantity ()+i); } // saia do armazém de Void Public MOVELOUT (int i) {mStorehouse.SetQuantity (mStorehouse.getQuantity ()-i); }} // Teste de manuseio de trabalhador Public class singlepattern {public static void main (string [] args) {storehouse mstorehouse1 = new storehouse (); Storehouse mStorehouse2 = novo Storehouse (); Transportadora de transportadora1 = nova transportadora (mStorehouse1); Carrier transportador2 = novo transportador (mStorehouse2); System.out.println ("Os dois são iguais?"); if (mstorehouse1.equals (mStorehouse2)) {// use é igual aqui em vez do símbolo ==, porque o símbolo == é apenas para comparar os endereços do sistema de dois objetos.out.println ("é o mesmo"); } else {System.out.println ("não é o mesmo"); } // Depois que o Porter move as mercadorias, relate a quantidade de mercadorias no transportador de armazém1.movein (30); System.out.println ("Margem do produto do armazém:"+Carrier1.mstorehouse.getquantity ()); Carrier2.moveout (50); System.out.println ("Margem do produto do armazém:"+carrier2.mstorehouse.getquantity ()); }}resultado:
Os dois são iguais? Margem do produto no mesmo armazém: 130 Margem do produto do armazém: 50
2. Introdução ao padrão de singleton
2.1 Problemas resolvidos (cenários de aplicação)
Conflito: A partir dos resultados acima, pode -se observar que os trabalhadores operavam obviamente não a mesma instância do armazém.
Objetivo: todos os trabalhadores operam a mesma instância do armazém
O padrão Singleton é uma solução para esse tipo de problema: implemente uma classe com apenas um objeto instanciado e fornece um Principado de Acesso Global 2.2 de trabalho
Em Java, operamos essas classes usando objetos (após a instanciação da classe). A instanciação da classe é realizada através de seu construtor . Se queremos implementar que uma classe tenha apenas um objeto instanciado, temos que trabalhar no construtor da classe:
Implementação geral do modo Singleton: (incluindo etapas de uso)
classe pública Singleton {// 1. Crie uma variável privada OurInstance (usado para gravar uma instância única de singleton) // 2. Instanciado singleton estático instanciado interno OurInstance = new Singleton (); // 3. Privatize o construtor da classe e impede as chamadas externas para instanciar a Singleton Private Singleton () {} // 4. Defina um método público para fornecer um ponto de acesso exclusivo global para a classe // 5. Retorne externamente uma instância exclusiva chamando o método getInstance () público estático estático singleton newInstance () {return OurInstance; }}Ok, você deve entender a introdução e os princípios do padrão Singleton, certo? Então, vamos resolver o problema de que "o armazém não é o mesmo" que apareceu acima de Xiaocheng!
2.3 Exemplo de introdução
Xiaocheng usa o modo singleton para melhorar o código do exemplo acima:
pacote scut.designmodel.singletonpattern; importar java.util.concurrent.locks.lock; importar java.util.concurrent.locks.reentrantlock; // singleton warehouse class storehouse {// a quantidade de produtos de armazenamento privado = 100; // Instanciado de armazenamento estático privado OurInstance = new Storehouse () ;; // Deixe o método de chamada externa O Método GetInstance () para retornar a instância exclusiva. Public Static Storehouse getInstance () {return OurInstance; } // Construtor fechado Storehouse Private () {} public void setQuantity (int Quantity) {this.quantity = Quantity; } public int getQuantity () {return Quantity; }} // transportadora de classe de homem de transportadora {public storehouse mstorehouse; operadora pública (armazém de armazém) {mstorehouse = storehouse; } // mova as mercadorias para o armazém vazio público Movein (int i) {mStorehouse.setquantity (mStorehouse.getquantity ()+i); } // saia do armazém de Void Public MOVELOUT (int i) {mStorehouse.SetQuantity (mStorehouse.getQuantity ()-i); }} // Teste de manuseio do trabalhador Public class singlepattern {public static void main (string [] args) {storehouse mstorehouse1 = storehouse.getInstance (); Storehouse mstorehouse2 = storehouse.getInstance (); Transportadora de transportadora1 = nova transportadora (mStorehouse1); Carrier transportador2 = novo transportador (mStorehouse2); System.out.println ("Os dois são iguais?"); if (mstorehouse1.equals (mstorehouse2)) {System.out.println ("é o mesmo"); } else {System.out.println ("não é o mesmo"); } // Depois que o Porter move as mercadorias, relate a quantidade de mercadorias no armazém, Carrier1.movein (30); System.out.println ("Margem do produto do armazém:"+Carrier1.mstorehouse.getquantity ()); Carrier2.moveout (50); System.out.println ("Margem do produto do armazém:"+carrier2.mstorehouse.getquantity ()); }}resultado:
São os dois iguais? É a mesma margem de commodities de armazém: 130 Margem de commodities de armazém: 80
De acordo com a análise dos resultados, depois de usar o modelo Singleton, existe apenas uma instância do armazém na aula de armazém, e não há necessidade de se preocupar com os carregadores que entram no armazém errado! ! !
2.4 Vantagens
2.5 Desvantagens
3. Implementação do modo singleton
3.1 Situação geral
Estilo faminto (o método de implementação mais simples de singleton)
classe singleton {private estático singleton OurInstance = new Singleton (); private singleton () {} public static singleton newInstance () {return OurInstance; }}Cenários de aplicativos:
Estilo preguiçoso
A maior diferença entre preguiçosos e famintos é o momento da operação de inicialização de singletons :
classe singleton {private estático singleton OurInstance = null; private singleton () {} public static singleton newInstance () {if (OurInstance == null) {OurInstance = new Singleton (); } retornar o OurInstance; }}Cenários de aplicativos:
3.2 Implementação do modo singleton em multithreading
No caso de multithreading:
Solução 1: Sincronize Lock
Use a sincronização de bloqueio sincronizado (singleton.class) para impedir que vários threads entrem simultaneamente, fazendo com que a instância seja instanciada várias vezes.
classe singleton {private estático singleton OurInstance = null; private singleton () {} public static singleton newInstance () {Synchronized (singleton.class) {if (OurInstance == null) {OurInstance = new Singleton (); }} retornar o OurInstance; }}Solução 2: trava de verificação dupla
Uma camada de IF é adicionada com base no bloqueio de sincronização (exceto sincronizado (singleton.class)) é melhorar o desempenho depois que a instância foi instanciada e na próxima vez que entrar, não precisa executar sincronizar (singleton.class) obter o bloqueio de objeto, melhorando o desempenho.
classe singleton {private estático singleton OurInstance = null; private singleton () {} public static singleton newInstance () {if (OurInstance == null) {Synchronized (singleton.class) {if (OurInstance == null) {OurInstance = new Singleton (); }}} retornar o OurInstance; }}Solução 3: classe interna estática
Quando a classe JVM carrega, os dados são sincronizados. Utilizamos a implementação da classe interna: Crie instâncias de objetos na classe interna.
Desde que o aplicativo não use a JVM de classe interna, a classe Singleton não será carregada e o objeto Singleton não será criado, alcançando assim o carregamento preguiçoso e a segurança dos threads preguiçosos.
classe Singleton {// O objeto Singleton será criado apenas quando a classe interna for carregada classe estática privada singleton2 {private static singleton OurInstance = new Singleton (); } private singleton () {} public static singleton newInstance () {return singleton2.ourinstance; }}Solução 4: Tipos de enumerar
O método de implementação de singleton mais simples e fácil de usar (recomendado por "Java eficaz")
public Enum Singleton {// Defina um elemento enum, que é uma instância da instância singleton; public void Dosomething () {}}Como usá -lo é o seguinte:
Singleton Singleton = Singleton.instance; Singleton.Dosomething ();
5. Resumo
Este artigo apresenta principalmente o modelo Singleton, incluindo os princípios e métodos de implementação. Em seguida, continuarei explicando outros modelos de design. Se você estiver interessado, pode continuar prestando atenção a ele.
Obrigado pela leitura, espero que isso possa ajudá -lo. Obrigado pelo seu apoio a este site!