シングルトン パターンは次のように述べています。 「インスタンスを 1 つだけ持ち、そのインスタンスへのグローバル アクセス ポイントを提供するクラスを定義します。」
言い換えれば、クラスは単一のインスタンスのみが作成され、単一のオブジェクトが他のすべてのクラスで使用できることを保証する必要があります。
シングルトン設計パターンには 2 つの形式があります
- 初期のインスタンス化: ロード時にインスタンスを作成します。
- 遅延インスタンス化: 必要に応じてインスタンスを作成します。
シングルトン設計パターンの利点
- リクエストごとにオブジェクトが作成されないため、メモリが節約されます。単一のインスタンスのみが何度も再利用されます。
シングルトン設計パターンの使用法
- シングルトン パターンは、主にマルチスレッド アプリケーションやデータベース アプリケーションで使用されます。これは、ロギング、キャッシュ、スレッド プール、構成設定などで使用されます。
シングルトン設計パターンの UML
シングルトン設計パターンを作成するにはどうすればよいですか?
シングルトン クラスを作成するには、クラスの静的メンバー、プライベート コンストラクター、静的ファクトリ メソッドが必要です。
- 静的メンバー: 静的であるため、メモリは 1 回だけ取得され、Singleton クラスのインスタンスが含まれます。
- プライベートコンストラクター: これにより、クラス外から Singleton クラスをインスタンス化できなくなります。
- 静的ファクトリーメソッド: これにより、Singleton オブジェクトへのグローバル アクセス ポイントが提供され、呼び出し元にインスタンスが返されます。
シングルトン パターンの初期インスタンス化を理解する
この場合、静的データメンバの宣言時にクラスのインスタンスを作成するので、クラスロード時にクラスのインスタンスが作成されます。
早期インスタンス化を使用したシングルトン設計パターンの例を見てみましょう。
ファイル: 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 } }
シングルトン パターンの遅延インスタンス化を理解する
この場合、同期メソッドや同期ブロックでクラスのインスタンスを作成するので、必要に応じてクラスのインスタンスが作成されます。
遅延インスタンス化を使用したシングルトン設計パターンの簡単な例を見てみましょう。
ファイル: 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 } }
シングルトン パターンにおけるクラスローダーの重要性
シングルトン クラスが 2 つのクラスローダーによってロードされる場合、シングルトン クラスのインスタンスが 2 つ (クラスローダーごとに 1 つずつ) 作成されます。
シングルトン パターンでのシリアル化の重要性
シングルトン クラスが Serializable の場合、シングルトン インスタンスをシリアル化できます。シリアル化したら、逆シリアル化できますが、シングルトン オブジェクトは返されません。
ビープラスツリー
この問題を解決するには、 readResolve() メソッド シングルトンを強制します。これは、オブジェクトが逆シリアル化された直後に呼び出されます。シングルトンオブジェクトを返します。
public class A implements Serializable { //your code of singleton protected Object readResolve() { return getA(); } }
シングルトン パターンの実際の例を理解する
- JDBCSingleton クラスを作成します。この JDBCSingleton クラスには、プライベートとしてのコンストラクターと、それ自体のプライベート静的インスタンス jdbc が含まれています。
- JDBCSingleton クラスは、静的インスタンスを外部に取得するための静的メソッドを提供します。ここで、JDBCSingletonDemo クラスは、JDBCSingleton クラスを使用して JDBCSingleton オブジェクトを取得します。
予測: mysql データベースに uid、uname、upassword の 3 つのフィールドを持つテーブル userdata を作成しました。データベース名はashwinirajput、ユーザー名はroot、パスワードはashwiniです。
ファイル: 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 classファイル: 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); } }
このシングルトン パターンの例をダウンロード