심오한 디자인 모델 - 단일 모드

1. 단일 모드 소개


2. 코드로 단일 모드 시범


3. 요약


1. 단일 모드 소개
정의: 이른바 단례 모델이란 특정한 방법을 취해 전체 소프트웨어 시스템에서 특정한 클래스에 하나의 실례만 존재할 수 있도록 보장하는 것이다. 그리고 이 클래스는 그 대상의 실례를 얻는 방법(정적 방법)만 제공한다.
설명: 어떤 때 우리 시스템은 전체적인 대상만 있으면 우리가 시스템의 전체적인 행위를 조율하고 자원을 절약하는 데 유리하다.예를 들어 1) 어떤 서비스에서 프로필을 읽을 대상이 필요하면 이런 대상이 프로필을 읽으면 충분하다.2) 예를 들어 우리는 지금 스레드 풀을 제공해야 한다. 대부분의 경우 스레드 풀과 같은 비교적 중량급 대상은 몇 개의 기능 모듈을 하나로 통일하면 충분하다. 왜냐하면 그는 상주 스레드 수가 있기 때문에 스레드 풀이 많으면 자원을 낭비할 수 있기 때문에 이 대상도 하나의 사례에 적합하다.
위의 두 가지 시나리오는 단일 시나리오의 객체만 사용하여 리소스를 절약하고 관리를 단순화합니다.
2. 코드로 단일 모드 시범
기본적인 실현 사고방식에서 알 수 있듯이 단일 모델은 하나의 서비스가 이런 대상(영원히 같은 대상)만 있고 이 실례를 얻는 방법만 요구한다.
이 요구에 따라 주로 다음과 같은 두 가지 절차가 이루어진다.
1) 구조 방법을 사유화하면 다른 코드는 이 클래스의 구조 방법으로 호출할 수 없고 new 방법으로 대상을 만들 수 없으며 이 클래스가 제공하는 정적 방법으로만 이 클래스의 유일한 실례를 얻을 수 있다.
2) 이 클래스에 정적 방법을 제공하면 이 방법을 호출할 때 단일 대상의 인용을 되돌려줍니다.
일례 모드는 모두 8가지 쓰기 방법이 있다. 1) 굶주림식(정적 상량) 2) 굶주림식(정적 코드 블록) 3) 게으름식(스레드가 안전하지 않다) 4) 게으름식(스레드 안전, 동기 쓰기) 5) 게으름식(스레드 안전, 동기 코드 블록) 6) 이중 검사 7) 정적 내부 클래스 8) 매거
각 쓰기 방법에 대해 살펴보겠습니다.
1) 아사자식(정적 상수 사용 가능)
public class Singleton {

    private static Object target = new Object();

    private Singleton() {
    }

    public static Object getInstance(){
        return target;
    }

}
장점: 쓰기는 비교적 간단하지만 클래스가 불러올 때 이미 실례화되었다.단점: 클래스를 불러올 때 초기화가 완료되어 lazy Loading 효과가 없습니다.만약 처음부터 끝까지 이 실례를 사용하지 않았다면 메모리 낭비를 초래할 수 있다.
2) 굶주림식(정적 코드 블록 사용 가능)
public class Singleton {

    private static Object target = new Object();

    private Singleton() {
    }

    public static Object getInstance(){
        return target;
    }
}
이런 방식은 사실 첫 번째 방식과 유사하며, 장단점도 마찬가지다.
3) 게으름뱅이식(스레드가 안전하지 않아 사용할 수 없음)
public class Singleton3 {

    private static Object target =  null;


    private Singleton3() {
    }

    public static Object getInstance(){
        if(target==null){
            target = new Object();
        }
        return target;
    }

}
장점: 게으름 피우는 효과가 있어 자원을 많거나 적게 절약할 수 있다.
단점: 단선정 모델에서만 적용됩니다. 다선정은 여러 개의 단례 대상을 만들어 자원 낭비를 초래할 수 있습니다.(스레드 A가if판단에 들어간 후에 타임슬립이 끝나고 다른 스레드 B도 이 문장을 통과한 다음에 스레드 A를 스케줄링하고 대상을 계속 만들면 여러 개의 실례가 발생한다.)
4) 게으름뱅이식(스레드 안전, 동기식 쓰기는 권장하지 않음)
public class Singleton4 {

    private static Object target =  null;


    private Singleton4() {
    }

    public static synchronized Object getInstance(){
        if(target==null){
            target = new Object();
        }
        return target;
    }
}
장점: 게으름 피우는 효과가 있고 라인도 안전합니다.
단점: 효율이 너무 낮아서 만들 뿐만 아니라 모든 라인이 실례를 얻으려면 동기화를 해야 한다. 사실은 실례를 만들 때 동기화를 하면 된다. 대상이 이미 존재하면 바로 되돌아오면 된다.
5) 게으름뱅이식(스레드 안전, 동기화 코드 블록은 사용할 수 없음)

public class Singleton5 {

    private static Object target = null;


    private Singleton5() {
    }

    public static Object getInstance() {
        if (target == null) {
            synchronized (Singleton5.class) {
                target = new Object();
            }
        }
        return target;
    }

}
장점: 네 번째 방안을 최적화하여 대상을 얻는 속도를 빨라지게 할 수 있다. 단점: 역시 라인 안전 문제가 있을 수 있다. (라인 A가if판단에 들어간 후에 타임슬립이 끝나고 다른 라인 B도 이 문장을 통과한 다음에 라인 A를 조정하고 계속 하나의 대상을 만들면 여러 가지 실례가 발생한다.)
6) 이중점검 권장
public class Singleton6 {

    private static Object target = null;


    private Singleton6() {
    }

    public static Object getInstance() {
        if (target == null) {
            synchronized (Singleton6.class) {
                if (target == null) {
                    target = new Object();
                }
            }
        }
        return target;
    }

}
장점: 두 번의 검사를 한 후에 다선정이 동시에 읽는 상황을 두려워하지 않는다.
7) 정적 내부 클래스 권장 사용
public class Singleton7 {


    private static class SingletonInstance {
        private static final Object target = new Object();
    }


    private Singleton7() {
    }

    public static Object getInstance() {
        return SingletonInstance.target;
    }

}
장점: 클래스의 정적 속성은 클래스를 처음 불러올 때만 초기화됩니다. 그래서 여기서 JVM은 루트의 안전성을 확보하고 클래스를 초기화할 때 다른 루트는 들어갈 수 없습니다.
8) 열거 추천 사용
public enum SingletonEnum {

    INSTANCE;
    
    public void doSomething() {
        System.out.println("doSomething");
    }

}
장점: 안전성과 유일성을 확보했다.단점: 그래서 실제 프로젝트 개발에서 이렇게 쓴 적이 드물다
3. 요약
단례 모델은 디자인 모델 중 가장 간단한 모델일 것이다.그것은 다음과 같은 몇 가지 요소가 있다. 1) 사유의 구조 방법 2) 자신의 실례를 가리키는 사유의 정적 인용 3) 자신의 실례를 반환값으로 하는 정적 공유의 방법
어떤 방식으로 얻느냐에 대해서는 일반적으로 상황을 보고 결정한다.

좋은 웹페이지 즐겨찾기