logo

Singleton-Entwurfsmuster in Java

  1. Singleton-Entwurfsmuster in Java
  2. Vorteil des Singleton-Musters
  3. Verwendung des Singleton-Musters
  4. Beispiel eines Singleton-Musters

Singleton Pattern sagt das genau „Definieren Sie eine Klasse, die nur eine Instanz hat und einen globalen Zugriffspunkt darauf bietet.“

Mit anderen Worten: Eine Klasse muss sicherstellen, dass nur eine einzelne Instanz erstellt wird und ein einzelnes Objekt von allen anderen Klassen verwendet werden kann.

Es gibt zwei Formen von Singleton-Entwurfsmustern

  • Frühe Instanziierung: Erstellung einer Instanz zur Ladezeit.
  • Faule Instanziierung: Erstellung einer Instanz bei Bedarf.

Vorteil des Singleton-Entwurfsmusters

  • Spart Speicher, da das Objekt nicht bei jeder Anforderung erstellt wird. Nur eine einzelne Instanz wird immer wieder verwendet.

Verwendung des Singleton-Entwurfsmusters

  • Das Singleton-Muster wird hauptsächlich in Multithread- und Datenbankanwendungen verwendet. Es wird für Protokollierung, Caching, Thread-Pools, Konfigurationseinstellungen usw. verwendet.

Uml of Singleton-Entwurfsmuster


Wie erstelle ich ein Singleton-Entwurfsmuster?

Um die Singleton-Klasse zu erstellen, benötigen wir ein statisches Mitglied der Klasse, einen privaten Konstruktor und eine statische Factory-Methode.

  • Statisches Mitglied: Aufgrund der statischen Aufladung wird der Speicher nur einmal abgerufen, er enthält die Instanz der Singleton-Klasse.
  • Privater Konstrukteur: Dadurch wird verhindert, dass die Singleton-Klasse von außerhalb der Klasse instanziiert wird.
  • Statische Factory-Methode: Dies stellt den globalen Zugriffspunkt auf das Singleton-Objekt bereit und gibt die Instanz an den Aufrufer zurück.

Grundlegendes zur frühen Instanziierung des Singleton-Musters

In einem solchen Fall erstellen wir die Instanz der Klasse zum Zeitpunkt der Deklaration des statischen Datenelements, sodass die Instanz der Klasse zum Zeitpunkt des Ladens der Klasse erstellt wird.

Sehen wir uns das Beispiel eines Singleton-Entwurfsmusters mit früher Instanziierung an.

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

Verstehen der verzögerten Instanziierung des Singleton-Musters

In einem solchen Fall erstellen wir die Instanz der Klasse in der synchronisierten Methode oder im synchronisierten Block, sodass die Instanz der Klasse bei Bedarf erstellt wird.

Sehen wir uns das einfache Beispiel eines Singleton-Entwurfsmusters mit verzögerter Instanziierung an.

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

Bedeutung des Klassenladers im Singleton-Muster

Wenn die Singleton-Klasse von zwei Klassenladern geladen wird, werden zwei Instanzen der Singleton-Klasse erstellt, eine für jeden Klassenlader.


Bedeutung der Serialisierung im Singleton-Muster

Wenn die Singleton-Klasse serialisierbar ist, können Sie die Singleton-Instanz serialisieren. Sobald es serialisiert ist, können Sie es deserialisieren, das Singleton-Objekt wird jedoch nicht zurückgegeben.

Java-Objektgleichheit

Um dieses Problem zu beheben, müssen Sie das außer Kraft setzen readResolve()-Methode das erzwingt den Singleton. Der Aufruf erfolgt direkt nach der Deserialisierung des Objekts. Es gibt das Singleton-Objekt zurück.

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

Reales Beispiel eines Singleton-Musters verstehen

  • Wir werden eine JDBCSingleton-Klasse erstellen. Diese JDBCSingleton-Klasse enthält ihren Konstruktor als privat und eine private statische JDBC-Instanz von sich selbst.
  • Die JDBCSingleton-Klasse stellt eine statische Methode bereit, um ihre statische Instanz nach außen zu übertragen. Jetzt verwendet die JDBCSingletonDemo-Klasse die JDBCSingleton-Klasse, um das JDBCSingleton-Objekt abzurufen.

Annahme: Sie haben eine Tabelle mit Benutzerdaten erstellt, die in der MySQL-Datenbank die drei Felder UID, Uname und UPassword enthält. Der Datenbankname ist ashwinirajput, der Benutzername ist root, das Passwort ist ashwini.

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

Laden Sie dieses Beispiel für ein Singleton-Muster herunter

Ausgabe