[java] singleton 패턴

심심이·2024년 3월 12일
0

java

목록 보기
45/46

싱글톤

클래스의 객체가 해당 프로세스에서 딱 하나만 만들어져있어야 하고 객체가 변경되면 안될때 사용
ex. 다크모드, db연결 커넥션

클래스의 객체가 해당 프로세스에서 1개만 만들어져야한다.

1.생성자 private로 만들면 다른 클래스에서 생성하지 못함
2.static으로 자기 자신인 변수를 하나 둠-> instance는 무한히 생성되지만 static으로 선언된 것들은 얼마나 만들어지든 스태틱 메모리에 딱 하나만 올라감(생성될때 공간이 딱 생성됨. 그래서 정적 변수라고 불리는 것임)
-> 처음엔 이게 null로 초기화 되어있음
처음이라면 스태틱에 올려주고,
그 다음에
이미 실행해서 만들어진 상태<라면 만들어진 그대로를 반환함. (return)

static메소드는 이미 스태틱 메모리에 정해진 공간을 차지했기 때문에 객체를 new로 생성하지 않고도 부를 수 있음.

   public void d_method() {
	      //SingletonNumber dObj = new SingletonNumber(); 
	      // 객체생성이 불가하다.
	      // 왜냐하면 SingletonNumber 생성자의 접근제한자를 private 으로 해두었기 때문이다.
	      
	      SingletonNumber dObj = SingletonNumber.getInstance(); // static 메소드 호출(접근제한자는 public 임)
	      
	      System.out.println("dObj =>" + dObj);
	      System.out.println("d_method() 메소드에서 cnt 값 호출 : " + dObj.getNextNumber());  
	   }
	   
   
   public void e_method() {
      // SingletonNumber eObj = new SingletonNumber(); 
      // 객체생성이 불가하다.
      // 왜냐하면 SingletonNumber 생성자의 접근제한자를 private 으로 해두었기 때문이다.
      
      SingletonNumber eObj = SingletonNumber.getInstance(); // static 메소드 호출(접근제한자는 public 임)
      
      System.out.println("eObj =>" + eObj);
      System.out.println("e_method() 메소드에서 cnt 값 호출 : " + eObj.getNextNumber());  
   }
   
   public void f_method() {
      // SingletonNumber fObj = new SingletonNumber(); 
      // 객체생성이 불가하다.
      // 왜냐하면 SingletonNumber 생성자의 접근제한자를 private 으로 해두었기 때문이다.
      
      SingletonNumber fObj = SingletonNumber.getInstance(); // static 메소드 호출(접근제한자는 public 임)
      
      System.out.println("fObj =>" + fObj);
      System.out.println("f_method() 메소드에서 cnt 값 호출 : " + fObj.getNextNumber());  
	   }
   
   
	   
public class SingletonNumber {

	// ================= singleton 패턴 만들기 시작 =================== //   
	/*
	    !!! === singleton 패턴에서 중요한 것은 다음의 3가지 이다  === !!!
	    
	    == 첫번째,
	       private 변수로 자기 자신의 클래스 인스턴스를 가지도록 해야 한다.
	       접근제한자가 private 이므로 외부 클래스에서는 직접적으로 접근이 불가하다.
	       또한 static 변수로 지정하여 SingletonNumber 클래스를 사용할 때 
	       객체생성은 딱 1번만 생성되도록 해야 한다.  
	*/   
	
	// --> field (첫번째로 작동) <-- //
	// static 변수로 만든다.
	private static SingletonNumber singleton; // = null과 같음
	
	// --> static 초기화 블럭(두번째로 작동)<-- //
	static {
		  // 중요한 사실은 static 초기화 블럭은 해당 클래스가 객체로 생성되기전에 먼저 실행되어지며,
	      // 딱 1번만 호출되어지고 다음번에 새로운 객체(인스턴스)를 매번 생성하더라도 
	      // static 초기화 블럭은 호출이 안되어진다.
		  System.out.println(">> ~~~ 확인용 SingletonNumber 클래스의 static 초기화 블럭 호출됨 <<");
		  
		  singleton = new SingletonNumber();
		  
	}
	
	// == 두번째,
	// 생성자에 접근제한자를 private 으로 지정하여, 외부에서 절대로 인스턴스를 생성하지 못하도록 막아버린다.
	private SingletonNumber() { }
	
	
	// == 세번째,
	// static 메소드를 생성[ 지금은 getInstance() ] 하여 외부에서 해당 클래스의 객체를 사용할 수 있도록 해준다.
	public static SingletonNumber getInstance() {
		return singleton; // static에서 딱 한번 만들어졌던 싱글톤 객체 반환.
	}
	
	// ================= singleton 패턴 만들기 끝 =================== //   
	
	private int cnt = 0; //인스턴스 변수
	
	public int getNextNumber() { //인스턴스 메소드
		return ++cnt; //인스턴스 변수
	}
	
	
	
}

싱글톤 실행

	
	
	public static void main(String[] args) {
		
		Main ma = new Main();

		ma.d_method();
		/*
		 dObj =>jdbc.day04.singletonPattern.SingletonNumber@24273305
		 d_method() 메소드에서 cnt 값 호출 : 1
		*/
		ma.e_method();
		/*
		 eObj =>jdbc.day04.singletonPattern.SingletonNumber@24273305
		 e_method() 메소드에서 cnt 값 호출 : 2
		 */
		ma.f_method();
		/*
		 fObj =>jdbc.day04.singletonPattern.SingletonNumber@24273305
		 f_method() 메소드에서 cnt 값 호출 : 3
		*/

		
		
	}

}
profile
개발하는 심심이

0개의 댓글

관련 채용 정보