logo

Patró de disseny Singleton en Java

  1. Patró de disseny Singleton en Java
  2. Avantatge del patró Singleton
  3. Ús del patró Singleton
  4. Exemple de patró Singleton

El patró Singleton només ho diu 'definir una classe que només té una instància i proporciona un punt d'accés global a ella'.

En altres paraules, una classe ha d'assegurar-se que només s'ha de crear una sola instància i que totes les altres classes puguin utilitzar un objecte únic.

Hi ha dues formes de patró de disseny singleton

  • Instanciació primerenca: creació de la instància en temps de càrrega.
  • Instanciació mandrosa: creació d'instàncies quan sigui necessari.

Avantatge del patró de disseny Singleton

  • Estalvia memòria perquè l'objecte no es crea a cada sol·licitud. Només es reutilitza una sola instància una i altra vegada.

Ús del patró de disseny Singleton

  • El patró Singleton s'utilitza principalment en aplicacions multifils i de bases de dades. S'utilitza en registres, emmagatzematge en memòria cau, agrupacions de fils, paràmetres de configuració, etc.

Patró de disseny Uml de Singleton


Com crear un patró de disseny Singleton?

Per crear la classe singleton, hem de tenir un membre estàtic de la classe, un constructor privat i un mètode de fàbrica estàtic.

  • Membre estàtic: Obté memòria només una vegada a causa de l'estàtica, conté la instància de la classe Singleton.
  • Constructor privat: Evitarà crear una instancia de la classe Singleton des de fora de la classe.
  • Mètode de fàbrica estàtica: Això proporciona el punt d'accés global a l'objecte Singleton i retorna la instància a la persona que truca.

Comprensió de la instanciació primerenca del patró Singleton

En aquest cas, creem la instància de la classe en el moment de declarar el membre de dades estàtiques, de manera que la instància de la classe es crea en el moment de la càrrega de la classe.

Vegem l'exemple del patró de disseny singleton utilitzant la instanciació primerenca.

Fitxer: 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 } } 

Entendre la instanciació mandrosa del patró Singleton

En aquest cas, creem la instància de la classe en mètode sincronitzat o bloc sincronitzat, de manera que es crea la instància de la classe quan es requereix.

Vegem l'exemple senzill de patró de disseny singleton que utilitza la instanciació mandrosa.

Fitxer: 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 } } 

Importància de Classloader en el patró Singleton

Si dos carregadors de classes carreguen la classe singleton, es crearan dues instàncies de classe singleton, una per a cada carregador de classes.


Importància de la serialització en el patró Singleton

Si la classe singleton és serializable, podeu serialitzar la instància singleton. Un cop serialitzat, podeu deserialitzar-lo, però no retornarà l'objecte singleton.

strsep c

Per resoldre aquest problema, heu d'anul·lar el fitxer mètode readResolve(). que fa complir el singleton. Es crida just després de deserialitzar l'objecte. Retorna l'objecte singleton.

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

Entendre l'exemple real del patró Singleton

  • Crearem una classe JDBCSingleton. Aquesta classe JDBCSingleton conté el seu constructor com a privat i una instància estàtica privada jdbc.
  • La classe JDBCSingleton proporciona un mètode estàtic per portar la seva instància estàtica al món exterior. Ara, la classe JDBCSingletonDemo utilitzarà la classe JDBCSingleton per obtenir l'objecte JDBCSingleton.

Suposició: heu creat una taula userdata que té tres camps uid, uname i upassword a la base de dades mysql. El nom de la base de dades és ashwinirajput, el nom d'usuari és root, la contrasenya és ashwini.

Fitxer: 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 
Fitxer: 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); } } 

descarregueu aquest exemple de patró Singleton

Sortida