진짜 개발자
본문 바로가기

Software Engineering/디자인패턴(Design Pattern)

싱글톤 패턴(Singleton Pattern)

728x90

싱글톤 패턴이란 

- 클래스 로더당 하나의 인스턴스만 존재할 수 있는 클래스



예를 들어
1. 학생들의 학점을 관리하는 관리 객체가 있다고 하자 
2. A학생 객체 , B학생 객체 , C학생 객체가 관리객체에 등록이 되고
3. 시험을 보고 시험점수가 관리객체에 저장이 되었다
4. 그런데 만약 관리 객체가 하나더 생성 되었다고 하자 이 때 A,B,C 학생들이 자신의 시험점수를
   새로 만들어진 관리 객체에 요구한다면 당연히 오류가 발생할 것이다.

이 처럼 객체가 여러개 존재 할 경우 오류가 발생할 확률이 있는 객체나
불필요하게 자원을 잡아먹는 경우를 방지하기 위해
객체를 하나만 유지하기 위해 사용되는 패턴이다.


사용법


 1번째 방법


public class Manager{
     private static Manager manager = new Manager();

     private Manager(){}

     public static Manager newInstance(){
          return manager;
     }
}
     1. 클래스 생성자를 private으로 설정 했기 때문에 외부에서 new로 생성이 불가
     2. static 메소드로 참조변수를 리턴하기 때문에 객체 또한 static 형으로 선언
         static메소드 이기 때문에 객체를 생성하지 않고 Factory.newInstance() 메소드가 사용가능 
     3. 결국 메소드를 통해서만 객체에 접근하므로 1개의 객체만이 유지됨
     
=> 이 방법은 클래스내에서 객체를 선언과 동시에 생성하므로 객체가 필요치 않더라도 클래스 정보가 메모리에 자동으로 적재되고 객체 또한 자동으로 적재된다 객체의 크기가 클 경우에  메모리를 많이차지하므로 좋지 않은 프로그래밍 방법이다.

2번째 방법 


public class Manager{
    private static Manager manager;

    private Manager(){}

    public static Manager newInstance(){
          if(manager == null){
              manager = new Manager();
          }
              return manager;            
     }
}
       
   => 이는 메소드 호출로 객체가 필요시에 생성된다는 장점이 있지만 다중 스레드 환경에서는 동시에 이 메소드에 접근하는 경우 여러 객체가 생성될 수 있는 가능성이 있다.


3번째 방법


public class Manager{
    private static Manager manager;

    private Manager(){}

    public static synchronized Manager newInstance(){
          if(manager == null){
               manager = new Manager();              
          }
              return manager;            
     }
}

=> 이는 메소드에 synchronized로 동기화를 하여 한번에 한 스레드만이 이영역을 사용하게 하므로써
    다중스레드 환경에서의 불안정한 것을 완화했지만 성능이 크게 감소한다..


4번째 방법 (initailzation on demand holder idiom)

    public class Manager{
     
        private class SingleTon{
             private static final SingleTon instance = new SingleTon();
        }

       public static Manager newInstance(){
           return SingleTon.instance;
        }
    }

    => 스레드 안정과 성능 메모리측면 모두를 만족시킨 방법이다