- Patrón de diseño singleton en Java
- Ventaja del patrón Singleton
- Uso del patrón Singleton
- Ejemplo de patrón singleton
El patrón Singleton dice que solo 'definir una clase que tiene sólo una instancia y proporciona un punto de acceso global a ella'.
En otras palabras, una clase debe garantizar que solo se cree una instancia y que todas las demás clases puedan utilizar un solo objeto.
Hay dos formas de patrón de diseño singleton.
- Creación de instancias tempranas: creación de instancia en el momento de la carga.
- Creación de instancias diferida: creación de instancia cuando sea necesario.
Ventaja del patrón de diseño Singleton
- Ahorra memoria porque el objeto no se crea en cada solicitud. Sólo una instancia se reutiliza una y otra vez.
Uso del patrón de diseño Singleton
- El patrón Singleton se utiliza principalmente en aplicaciones de bases de datos y subprocesos múltiples. Se utiliza en registro, almacenamiento en caché, grupos de subprocesos, ajustes de configuración, etc.
Uml del patrón de diseño Singleton
¿Cómo crear un patrón de diseño Singleton?
Para crear la clase singleton, necesitamos tener un miembro estático de la clase, un constructor privado y un método de fábrica estático.
- Miembro estático: Obtiene memoria solo una vez debido a la estática y contiene la instancia de la clase Singleton.
- Constructor privado: Evitará crear una instancia de la clase Singleton desde fuera de la clase.
- Método de fábrica estática: Esto proporciona el punto global de acceso al objeto Singleton y devuelve la instancia a la persona que llama.
Comprender la creación de instancias tempranas del patrón Singleton
En tal caso, creamos la instancia de la clase en el momento de declarar el miembro de datos estáticos, por lo que la instancia de la clase se crea en el momento de la carga de la clase.
Veamos el ejemplo del patrón de diseño singleton que utiliza la creación de instancias tempranas.
Archivo: A.javaclass 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 } }
Comprender la creación de instancias diferidas del patrón Singleton
En tal caso, creamos la instancia de la clase en un método sincronizado o bloque sincronizado, por lo que se crea una instancia de la clase cuando sea necesario.
Veamos el ejemplo simple de un patrón de diseño singleton que utiliza la creación de instancias diferidas.
Archivo: A.javaclass 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 } }
Importancia del cargador de clases en el patrón Singleton
Si dos cargadores de clases cargan la clase singleton, se crearán dos instancias de clase singleton, una para cada cargador de clases.
Importancia de la serialización en el patrón Singleton
Si la clase singleton es serializable, puede serializar la instancia singleton. Una vez serializado, puede deserializarlo pero no devolverá el objeto singleton.
es grasa proteica
Para resolver este problema, debe anular el método leerResolve() que hace cumplir el singleton. Se llama justo después de deserializar el objeto. Devuelve el objeto singleton.
public class A implements Serializable { //your code of singleton protected Object readResolve() { return getA(); } }
Comprensión del ejemplo real del patrón Singleton
- Vamos a crear una clase JDBCSingleton. Esta clase JDBCSingleton contiene su constructor como privado y una instancia estática privada jdbc de sí misma.
- La clase JDBCSingleton proporciona un método estático para llevar su instancia estática al mundo exterior. Ahora, la clase JDBCSingletonDemo utilizará la clase JDBCSingleton para obtener el objeto JDBCSingleton.
Suposición: ha creado una tabla de datos de usuario que tiene tres campos uid, uname y uppassword en la base de datos mysql. El nombre de la base de datos es ashwinirajput, el nombre de usuario es root y la contraseña es ashwini.
Archivo: JDBCSingleton.javaimport 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 classArchivo: 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); } }
descargue este ejemplo de patrón Singleton