ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OOP 디자인 패턴 : 두번째 생성패턴] 싱글톤 패턴 (Singleton pattern)
    프로그래밍/기타 2023. 5. 21. 13:18
    반응형

     

     

    객체 생성

    객체 생성이란 선언된 클래스에 따른 객체를 메모리에 할당하는 동작

    new 키워드를 통해 반복생성 할 수 있다

    class Hello {
    	public String greeting() {
        	return "안녕하세요";
        }
    }
    // 객체 생성
    Hello obj = new Hello();

     

    클래스를 이용해 동일한 객체를 무제한으로 생성 가능하다!

     

    싱글톤 패턴

    싱글톤은 하나의 객체만 생성하도록 제한하는 패턴

    생성된 객체는 공유되어 어디서든 접근이 가능하다

    공유 자원 접근, 복수의 시스템이 하나의 잡원에 접근, 유일한 객체가 필요, 값의 캐시가 필요할 때 등등 사용된다.

     

    싱글턴 설계
    public class Config 
    {
        private static Config instance; 
        
        private Config() { }
        
        public static Config getInstance()
        {
            if (instance == null)
            {
                synchronized(Config.class)
                {
                    innstance = new Config();
                }
            }
            
            return instance;
        }
    }

     

     

    1. 외부에서 생성자에 접근 못하도록 private (내부적인 접근만 허용) 접근 권한으로 변경

    public class Config 
    {
        private Config() { }
    }

     

    2.생성 메서드 생성

    객체 생성은 new 키워드로만 가능하다. 그러면 외부적으로 고립된 싱글턴 객체를 어떻게 만들어야 할까?

    내부적으로 객체를 생성할 수 있도록 특수한 메서드 생성한다.

    public class Config 
    {
    
        private Config() {}
        
        public static Config getInstance()
        {
            return new Config();
        }
    }

    getInstance() 메서드는 자기 자신의 클래스를 객체로 생성하여 반환한다.

    싱글턴 클래스는 아직 객체가 존재하지 않으므로, 정적 타입으로 메서드를 선언하여 객체 없이도 메서드를 호출할 수 있게한다.

     

    3. 참조체 추가

    public class Config 
    {
        private static Config instance; // 참조체
        
        private Config() {}
        
         public static Config getInstance()
        {
            if (instance == null)
            {
                synchronized(Config.class)
                {
                    innstance = new Config();
                }
            }
            
            return instance;
        }
    }

    getInstance() 호출시 매번 다른 객체를 생성하여 반환한다.

    싱글턴 패턴은 어떤 경우라도 1개의 객체만 생성해야 한다. 자체 객체를 저장하는 참조체를 갖고 있다.

    참조체를 통해 자신의 객체가 생성되었는지 판단한다.

    if 조건을 통해 참조체의 객체 존재 여부를 검사하고, 공유되는 객체가 있을 경우 참조체를 반환한다.

     

    싱글턴은 안티패턴?

    멀티 스레드 환경에서 싱글턴 패턴을 사용할 때는 주의해야 한다.

    멀티 스레드 환경에서 싱글턴의 객체 생성이 동시에 요청되는 경우 경합성이 발생한다.

    경합성?
    2개 이상의 스레드가 동일한 자원을 사용하는 경우 충돌 => 2개의 객체가 만들어지는 오류 발생!! 

    이러한 문제를 해결하기 위해 늦은 바인딩을 사용한다. 

    늦은 바인딩?
    싱글턴 패턴은 클래스에 객체를 요청할 때 객체를 생성하여 자원(메모리)에 할당한다.

    늦은 바인딩을 통해 객체 생성을 동적으로 처리한다. 하지만 늦은 바인딩도 경합성 충돌을 해결할 수 없다!

     

    경합성과 늦은 초기화 문제를 좀 더 보완하기 위해 시스템 부팅 시 필요한 싱글턴의 객체를 미리 생성한다.

    싱글턴으로 처리할 부분을 부팅시 미리 처리한다면 참조체를 구별하는 IF문의 오동작 방지가 가능하다.

    하지만 프로그램 실행 중 한번도 사용되지 않는다?

     

    => 메모리 낭비가 발생한다.

     

    메모리의 관리

    메모리 자원은 유한하므로 효율적인 관리 필요하다!

    싱글턴은 시스템에 유일한 객체를 생성한다.

    자원이 필요할 때 동적으로 할당받을 수 있지만, 정적으로 생성된 자원을 해제하여 반환하기는 어렵다.

    싱글턴으로 생성한 객체는 공유자원으로 분류한다. 언제 쓰일지 모르기 때문에 프로그램이 종료될 때까지 생존한다.

     

    => 역시 메모리 낭비가 발생한다.

     

     

    반응형

    댓글

Designed by Tistory.