클래스의 객체가 해당 프로세스에서 딱 하나만 만들어져있어야 하고 객체가 변경되면 안될때 사용
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
*/
}
}