logo

Padrão de design singleton em Java

  1. Padrão de design singleton em Java
  2. Vantagem do padrão Singleton
  3. Uso do padrão Singleton
  4. Exemplo de padrão Singleton

O Padrão Singleton diz que apenas 'define uma classe que possui apenas uma instância e fornece um ponto global de acesso a ela'.

Em outras palavras, uma classe deve garantir que apenas uma única instância seja criada e que um único objeto possa ser usado por todas as outras classes.

Existem duas formas de padrão de design singleton

  • Instanciação antecipada: criação de instância no momento do carregamento.
  • Instanciação preguiçosa: criação de instância quando necessário.

Vantagem do padrão de design Singleton

  • Economiza memória porque o objeto não é criado a cada solicitação. Apenas uma única instância é reutilizada continuamente.

Uso do padrão de design Singleton

  • O padrão Singleton é usado principalmente em aplicativos multithread e de banco de dados. Ele é usado em log, cache, pools de threads, definições de configuração, etc.

Uml do padrão de design Singleton


Como criar um padrão de design Singleton?

Para criar a classe singleton, precisamos ter um membro estático da classe, um construtor privado e um método de fábrica estático.

  • Membro estático: Ele obtém memória apenas uma vez por causa da estática, contém a instância da classe Singleton.
  • Construtor privado: Isso impedirá a instanciação da classe Singleton de fora da classe.
  • Método de fábrica estático: Isso fornece o ponto global de acesso ao objeto Singleton e retorna a instância ao chamador.

Compreendendo a instanciação inicial do padrão Singleton

Nesse caso, criamos a instância da classe no momento da declaração do membro de dados estáticos, portanto, a instância da classe é criada no momento do carregamento da classe.

Vamos ver o exemplo do padrão de design singleton usando instanciação inicial.

Arquivo: A.java
 class A{ private static A obj=new A();//Early, instance will be created at load time private A(){} public static A getA(){ return obj; } public void doSomething(){ //write your code } } 

Compreendendo a instanciação preguiçosa do padrão Singleton

Nesse caso, criamos a instância da classe no método sincronizado ou bloco sincronizado, para que a instância da classe seja criada quando necessário.

Vamos ver o exemplo simples de padrão de design singleton usando instanciação lenta.

Arquivo: A.java
 class A{ private static A obj; private A(){} public static A getA(){ if (obj == null){ synchronized(Singleton.class){ if (obj == null){ obj = new Singleton();//instance will be created at request time } } } return obj; } public void doSomething(){ //write your code } } 

Significado do Classloader no padrão Singleton

Se a classe singleton for carregada por dois carregadores de classe, duas instâncias da classe singleton serão criadas, uma para cada carregador de classe.


Significado da serialização no padrão Singleton

Se a classe singleton for Serializable, você poderá serializar a instância singleton. Depois de serializado, você pode desserializá-lo, mas ele não retornará o objeto singleton.

verificação java é nula

Para resolver esse problema, você precisa substituir o Método readResolve() que impõe o singleton. É chamado logo após o objeto ser desserializado. Ele retorna o objeto singleton.

 public class A implements Serializable { //your code of singleton protected Object readResolve() { return getA(); } } 

Compreendendo um exemplo real de padrão Singleton

  • Vamos criar uma classe JDBCSingleton. Esta classe JDBCSingleton contém seu construtor como privado e uma instância estática privada jdbc de si mesmo.
  • A classe JDBCSingleton fornece um método estático para levar sua instância estática para o mundo externo. Agora, a classe JDBCSingletonDemo usará a classe JDBCSingleton para obter o objeto JDBCSingleton.

Suposição: você criou uma tabela userdata que possui três campos uid, uname e uppassword no banco de dados mysql. O nome do banco de dados é ashwinirajput, o nome de usuário é root, a senha é ashwini.

Arquivo: JDBCSingleton.java
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; class JDBCSingleton { //Step 1 // create a JDBCSingleton class. //static member holds only one instance of the JDBCSingleton class. private static JDBCSingleton jdbc; //JDBCSingleton prevents the instantiation from any other class. private JDBCSingleton() { } //Now we are providing gloabal point of access. public static JDBCSingleton getInstance() { if (jdbc==null) { jdbc=new JDBCSingleton(); } return jdbc; } // to get the connection from methods like insert, view etc. private static Connection getConnection()throws ClassNotFoundException, SQLException { Connection con=null; Class.forName('com.mysql.jdbc.Driver'); con= DriverManager.getConnection('jdbc:mysql://localhost:3306/ashwanirajput', 'root', 'ashwani'); return con; } //to insert the record into the database public int insert(String name, String pass) throws SQLException { Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement('insert into userdata(uname,upassword)values(?,?)'); ps.setString(1, name); ps.setString(2, pass); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } //to view the data from the database public void view(String name) throws SQLException { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con=this.getConnection(); ps=con.prepareStatement('select * from userdata where uname=?'); ps.setString(1, name); rs=ps.executeQuery(); while (rs.next()) { System.out.println('Name= '+rs.getString(2)+'	'+'Paasword= '+rs.getString(3)); } } catch (Exception e) { System.out.println(e);} finally{ if(rs!=null){ rs.close(); }if (ps!=null){ ps.close(); }if(con!=null){ con.close(); } } } // to update the password for the given username public int update(String name, String password) throws SQLException { Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement(' update userdata set upassword=? where uname=''+name+'' '); ps.setString(1, password); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } // to delete the data from the database public int delete(int userid) throws SQLException{ Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement(' delete from userdata where uid=''+userid+'' '); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } }// End of JDBCSingleton class 
Arquivo: JDBCSingletonDemo.java
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; class JDBCSingletonDemo{ static int count=1; static int choice; public static void main(String[] args) throws IOException { JDBCSingleton jdbc= JDBCSingleton.getInstance(); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); do{ System.out.println('DATABASE OPERATIONS'); System.out.println(' --------------------- '); System.out.println(' 1. Insertion '); System.out.println(' 2. View '); System.out.println(' 3. Delete '); System.out.println(' 4. Update '); System.out.println(' 5. Exit '); System.out.print('
'); System.out.print('Please enter the choice what you want to perform in the database: '); choice=Integer.parseInt(br.readLine()); switch(choice) { case 1:{ System.out.print('Enter the username you want to insert data into the database: '); String username=br.readLine(); System.out.print('Enter the password you want to insert data into the database: '); String password=br.readLine(); try { int i= jdbc.insert(username, password); if (i>0) { System.out.println((count++) + ' Data has been inserted successfully'); }else{ System.out.println('Data has not been inserted '); } } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }//End of case 1 break; case 2:{ System.out.print('Enter the username : '); String username=br.readLine(); try { jdbc.view(username); } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }//End of case 2 break; case 3:{ System.out.print('Enter the userid, you want to delete: '); int userid=Integer.parseInt(br.readLine()); try { int i= jdbc.delete(userid); if (i>0) { System.out.println((count++) + ' Data has been deleted successfully'); }else{ System.out.println('Data has not been deleted'); } } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }//End of case 3 break; case 4:{ System.out.print('Enter the username, you want to update: '); String username=br.readLine(); System.out.print('Enter the new password '); String password=br.readLine(); try { int i= jdbc.update(username, password); if (i>0) { System.out.println((count++) + ' Data has been updated successfully'); } } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }// end of case 4 break; default: return; } } while (choice!=4); } } 

baixe este exemplo de padrão Singleton

Saída