logo

Java의 싱글톤 디자인 패턴

  1. Java의 싱글톤 디자인 패턴
  2. 싱글톤 패턴의 장점
  3. 싱글톤 패턴의 활용
  4. 싱글톤 패턴의 예

싱글톤 패턴은 다음과 같이 말합니다. '인스턴스가 하나만 있고 이에 대한 전역 액세스 지점을 제공하는 클래스를 정의합니다.'

즉, 클래스는 단일 인스턴스만 생성되어야 하며 단일 개체를 다른 모든 클래스에서 사용할 수 있도록 보장해야 합니다.

싱글턴 디자인 패턴에는 두 가지 형태가 있습니다.

  • 초기 인스턴스화: 로드 시 인스턴스 생성.
  • 지연 인스턴스화: 필요할 때 인스턴스 생성.

싱글턴 디자인 패턴의 장점

  • 각 요청마다 객체가 생성되지 않으므로 메모리가 절약됩니다. 단일 인스턴스만 계속해서 재사용됩니다.

싱글턴 디자인 패턴의 활용

  • 싱글톤 패턴은 주로 다중 스레드 및 데이터베이스 응용 프로그램에서 사용됩니다. 로깅, 캐싱, 스레드 풀, 구성 설정 등에 사용됩니다.

싱글톤 디자인 패턴의 Uml


싱글톤 디자인 패턴을 만드는 방법은 무엇입니까?

싱글톤 클래스를 생성하려면 클래스의 정적 멤버, 전용 생성자 및 정적 팩토리 메서드가 필요합니다.

  • 정적 멤버: 정적 때문에 메모리를 한 번만 가져오며 Singleton 클래스의 인스턴스를 포함합니다.
  • 개인 생성자: 클래스 외부에서 Singleton 클래스를 인스턴스화하는 것을 방지합니다.
  • 정적 팩토리 메소드: 이는 Singleton 개체에 대한 전역 액세스 지점을 제공하고 인스턴스를 호출자에게 반환합니다.

싱글톤 패턴의 초기 인스턴스화 이해

이 경우 정적 데이터 멤버 선언 시 클래스의 인스턴스를 생성하므로 클래스 로딩 시 클래스의 인스턴스가 생성됩니다.

초기 인스턴스화를 사용한 싱글톤 디자인 패턴의 예를 살펴보겠습니다.

파일: 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 } } 

싱글톤 패턴의 지연 인스턴스화 이해

이런 경우에는 동기화 메소드나 동기화 블록에서 클래스의 인스턴스를 생성하므로 필요할 때 클래스의 인스턴스가 생성됩니다.

지연 인스턴스화를 사용한 싱글톤 디자인 패턴의 간단한 예를 살펴보겠습니다.

파일: 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 } } 

싱글톤 패턴에서 클래스로더의 중요성

싱글톤 클래스가 두 개의 클래스로더에 의해 로드되면 각 클래스로더에 대해 하나씩, 두 개의 싱글톤 클래스 인스턴스가 생성됩니다.


싱글톤 패턴에서 직렬화의 중요성

싱글톤 클래스가 직렬화 가능하면 싱글톤 인스턴스를 직렬화할 수 있습니다. 직렬화되면 역직렬화할 수 있지만 싱글톤 개체를 반환하지 않습니다.

js 여러 줄 문자열

이 문제를 해결하려면 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 및 uppassword 세 개의 필드가 있는 userdata 테이블을 생성했습니다. 데이터베이스 이름은 ashwinirajput, 사용자 이름은 root, 비밀번호는 ashwini입니다.

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

이 싱글턴 패턴 예제를 다운로드하세요

산출