본문 바로가기

책리뷰/헤드퍼스트 디자인패턴

헤드퍼스트 디자인패턴 - 싱글턴 패턴

728x90
반응형

목차

     

    고전적인 싱글턴 패턴 구현법


     

    public class Singleton {
        private static Singleton uniqueInstance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if(uniqueInstance == null) {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
        
    }

    Singleton클래스의 인스턴스를 저장하는 정적 변수를 선언 후 getInstance()메소드를 통해 인스턴스 생성한다.

     

     

    싱글턴 패턴의 정의


    싱글턴 패턴은 클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공한다.

     

    • 실제로 하나뿐인 인스턴스를 관리하도록 만들면 된다. 다른 어떤 클래스도 추가로 인스턴스를 만들지 못하게 해야한다.
    • 어디서든 인스턴스에 접근할 수 있도록 전역 접근 지점을 제공한다. 게으른 방식으로 생성되도록 구현할 수 있다.

     

     

    멀티스레딩 문제


    2개의 스레드에서 instance 생성 코드를 실행할 경우 

    public static ChocolateBoiler getInstance() {
        if(uniqueInstance == null) {
            uniqueInstance = new ChocolateBoiler();
        }
        return uniqueInstance;
    }

    하나의 스레드에서 uniqueInstance가 null임을 확인하고 인스턴스를 생성하는 도중 다른 스레드에서도 생성할 경우 인스턴스는 두 개가 된다.

     

     

    멀티스레딩 문제 해결


    public class Singleton {
        private static Singleton uniqueInstance;
    
        private Singleton() {}
    
        public static synchronized Singleton getInstance() {
            if(uniqueInstance == null) {
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
        }
        
    }

    synchronized => 한 스레드가 메소드 사용을 끝내기전까지 다른 스레드는 기다려야 한다. 

    그러나 속도가 문제가 될 수 있다. 

    처음 인스턴스를 생성할 때를 제외하면 동기화된 상태로 유지할 필요가 없다.

     

     

    다른 방법 - 처음부터 생성

    인스턴스가 필요할때 말고 처음부터 만든다.

    public class Singleton {
    
        private static Singleton uniqueInstance = new Singleton();
        private Singleton() {}
    
        public static synchronized Singleton getInstance() {
            return uniqueInstance;
        }
        
    }

    클래스가 로딩될때 하나뿐인 Singleton의 인스턴스를 성한다. 

     

     

    다른 방법 - DCL 

    Double-checked locking : 인스턴스가 생성되어있는지 확인한 다음 생성되지 않았을 때만 동기화.

     

    public class Singleton {
        private volatile static Singleton uniqueInstance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if(uniqueInstance == null) {
                synchronized (Singleton.class) {
                    if(uniqueInstance == null) {
                        uniqueInstance = new Singleton();
                    }
                }
            }
            return uniqueInstance;
        }
        
    }

    volatile 

    JAVA변수를 Main memory에 저장하겠다는 것을 명시하는 키워드

     

    DCL은 자바 1.4이전 버전에서 쓸 수 없다.

     

     

    enum을 통해 싱글턴 문제 해결


    public enum Singleton {
        UNIQUE_INSTANCE;
    }
    
    public class SingletonClient {
        public static void main(String[] args) {
            Singleton singleton = Singleton.UNIQUE_INSTANCE;
        }
    }

     

     

     

    객체지향 원칙


    • 바뀌는 부분은 캡슐화한다.
    • 상속보다는 구성을 활용한다.
    • 구현보다는 인터페이스에 맞춰서 프로그래밍한다.
    • 상호작용하는 객체사이에서는 가능하면 느슨한 결합을 사용해야 한다.
    • 클래스는 확장에는 열려있어야 하지만 변경에는 닫혀있어야 한다.
    • 추상화된 것에 의존하게 만들고 구상 클래스에 의존하지 않게 만든다.
    728x90
    반응형