[프로 그래 밍 소질] 디자인 모델 - 단일 모드 (Singleton pattern)

1, 개념
단일 모드 (Singleton pattern, 단일 모드, 단일 모드): 하나의 인 스 턴 스 만 있 는 지 확인 하고 전체 액세스 점 을 제공 합 니 다.
단일 디자인 모델 은 디자인 모델 에서 간단 하고 자주 사용 하 는 것 이다.
2, 장면
1) 장면
단일 모드 는 하나의 대상 만 만 만 들 수 있 기 때문에 메모 리 를 절약 하고 대상 의 접근 속 도 를 가속 화하 기 때문에 대상 은 공용 장소 에서 사용 하기에 적합 해 야 한다. 예 를 들 어 여러 모듈 이 같은 데이터 원본 연결 대상 을 사용 하 는 등 이다.① 자원 공유 의 경우 자원 조작 시 발생 하 는 성능 이나 손실 등 을 피한다.위 로그 파일 과 같이 설정 을 적용 합 니 다.② 자원 을 통제 하 는 상황 에서 자원 간 의 상호 통신 을 편리 하 게 한다.스 레 드 탱크 등.
2) 사용
① 잦 은 정례 화 및 폐기 대상 이 필요 하 다.② 대상 을 만 드 는 데 너무 오래 걸 리 거나 자원 을 너무 많이 소모 하지만 자주 사용 하 는 대상.③ 상태 가 있 는 도구 류 대상.④ 데이터베이스 나 파일 에 자주 접근 하 는 대상.
3) 예시
① 외부 자원: 컴퓨터 마다 프린터 가 몇 개 있 지만 하나의 Printer Spooler 만 있어 서 두 개의 인쇄 작업 이 동시에 프린터 에 출력 되 지 않도록 합 니 다.내부 자원: 대부분의 소프트웨어 는 하나의 (또는 여러 개) 속성 파일 저장 시스템 설정 이 있 습 니 다. 이러한 시스템 은 하나의 대상 이 이러한 속성 파일 을 관리 해 야 합 니 다 ② Windows 의 Task Manager (작업 관리자) 는 전형 적 인 단일 모드 입 니 다. (이것 은 익숙 하 죠?) 생각해 보 세 요. 그 렇 죠? windows task manager 두 개 를 열 수 있 습 니까?못 믿 겠 으 면 직접 해 보 세 요. ③ windows 의 휴지통 (휴지통) 도 전형 적 인 애플 리 케 이 션 입 니 다.전체 시스템 이 실행 되 는 과정 에서 휴지통 은 유일한 인 스 턴 스 를 유지 해 왔 다.④ 사이트 의 계수 기 는 일반적으로 단일 모델 로 이 루어 지 며 그렇지 않 으 면 동기 화 되 기 어렵다.⑤ 프로그램의 로그 애플 리 케 이 션 은 일반적으로 단일 모드 로 이 루어 집 니 다. 공 유 된 로그 파일 이 계속 열 려 있 기 때 문 입 니 다. 하나의 인 스 턴 스 만 작 동 할 수 있 기 때 문 입 니 다. 그렇지 않 으 면 내용 이 추가 되 지 않 습 니 다.⑥ 웹 애플 리 케 이 션 의 설정 대상 을 읽 고 단일 모드 도 사용 합 니 다. 이것 은 설정 파일 이 공 유 된 자원 이기 때 문 입 니 다.⑦ 데이터베이스 연결 탱크 의 디자인 도 보통 단일 모델 을 사용 합 니 다. 데이터베이스 연결 은 데이터베이스 자원 이기 때 문 입 니 다.데이터베이스 소프트웨어 시스템 에서 데이터베이스 연결 탱크 를 사용 하 는 것 은 주로 데이터베이스 연결 을 열거 나 닫 는 데 발생 하 는 효율 적 인 손실 을 절약 하 는 것 이다. 이런 효율 적 인 손실 은 여전히 매우 비싸다. 왜냐하면 단일 모델 로 유지 하면 이런 손실 을 크게 줄 일 수 있 기 때문이다.⑨ 다 중 스 레 드 탱크 의 디자인 도 보통 단일 모델 을 사용 하 는데 이것 은 스 레 드 탱크 가 연못 의 스 레 드 를 편리 하 게 제어 해 야 하기 때문이다.⑨ 운영 체제 의 파일 시스템 도 큰 단일 모델 이 실현 하 는 구체 적 인 예 이 고 하나의 운영 체제 에 하나의 파일 시스템 만 있 을 수 있 습 니 다.⑩ HttpApplication 도 하나의 전형 적 인 응용 이다.ASP. Net (IIS) 의 전체 요청 수명 주 기 를 잘 아 는 사람 은 HttpApplication 도 하나의 예 모드 임 을 알 아야 합 니 다. 모든 HttpModule 은 하나의 HttpApplication 인 스 턴 스 를 공유 합 니 다. 전체 9322 ° 한 서버 프로그램 에서 이 서버 의 설정 정 보 는 하나의 파일 에 저 장 됩 니 다. 이 배치 데 이 터 는 하나의 단일 대상 이 통일 적 으로 읽 습 니 다.그리고 서비스 프로 세 스 의 다른 대상 은 이 단일 대상 을 통 해 이 설정 정 보 를 가 져 옵 니 다.이런 방식 은 복잡 한 환경 에서 의 배치 관 리 를 간소화 했다.
3, 장단 점
우수 하 다.
① 전역 변수의 교체
단일 부품 은 실례 화 를 늦 출 수 있다.
② 대상 의 유일 성 보장
공유 자원 에 대한 다 중 점용 을 피 했다.여러 개의 인 스 턴 스 로 인 한 문 제 를 해결 했다. 예 를 들 어 프로그램의 행위 이상, 자원 의 과도 한 사용, 일치 하지 않 는 결과 등 이다.다른 클래스 에서 몇 개의 단일 인 스 턴 스 를 만 들 었 든 메모리 에 만 있 는 단일 인 스 턴 스 입 니 다.
모자라다
① 변화 하 는 대상 에 적용 되 지 않 는 다
만약 에 같은 유형의 대상 이 서로 다른 장면 에서 변 화 를 일 으 키 려 면 단일 모델 은 데이터 의 오 류 를 초래 하고 서로의 상 태 를 저장 할 수 없다.
② 단일 모드 남용
만약 에 자원 을 절약 하기 위해 데이터베이스 연결 탱크 대상 을 단일 클래스 로 설계 하면 공유 연결 탱크 대상 의 프로그램 이 너무 많아 서 연결 탱크 가 넘 칠 수 있다.만약 실례 화 된 대상 이 장시간 이용 되 지 않 는 다 면 시스템 은 쓰레기 로 여 겨 져 회수 되 고 이 는 대상 상태의 분실 을 초래 할 것 이다.사용 주의사항:
4, 실현
(1) 디자인 모델 의 실현
이 인 스 턴 스 의 전역 접근 점 을 제공 합 니 다. 인 스 턴 스 가 필요 할 때 단일 클래스 를 조회 하여 하나의 인 스 턴 스 를 되 돌려 줍 니 다.
① 구조 함 수 를 민영화 한다.
다른 프로그램 이 이러한 대상 을 너무 많이 만 드 는 것 을 피하 기 위해 서 는 다른 프로그램 이 이러한 대상 을 만 드 는 것 을 금지한다.
② 클래스 에 이 클래스 의 대상 을 만 듭 니 다.
다른 프로그램 이 이러한 대상 에 접근 할 수 있 도록 이 클래스 에서 대상 을 사용자 정의 합 니 다.
③ 대상 을 얻 을 수 있 는 방법 을 제공한다.
다른 프로그램 이 사용자 정의 대상 에 접근 하 는 것 을 편리 하 게 하기 위해 서 는 대외 적 으로 접근 방식 을 제공 할 수 있다.(다크호스 프로그래머 참조)
2) 안 드 로 이 드 의 단일 모드
① activity 의 단일 예 모드
Android 에서 xml 이 구현 되 고 activity 의 시작 모드 를 설정 합 니 다.Android 에서 상기 실현 방법 을 제외 하고 Activity 에 대한 단일 모드 는 AndroidMainfest. xml 에서 다음 코드 를 정의 하여 이 루어 집 니 다.
android:launchMode="singleInstance"

② 다른 유형의 단일 사례 모델
Fragment 를 포함 하여 GOF 단일 모드 로 하면 됩 니 다.
③Application
응용 프로그램 이 비교적 특수 하고 구체 적 인 표기 법 참고: Context 류 와 응용 프로그램 류
public class MyApplicationextends Application {

    private static MyApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public static AndroidApplication getInstance(){
        return instance;
    }
}

④ 단일 모델 의 응용
i > 입력 클래스 InputMethodManager
public final class InputMethodManager {
    //          
    static InputMethodManager sInstance;

    //  api  
    public static InputMethodManager getInstance() {
        synchronized (InputMethodManager.class) {
            if (sInstance == null) {
                IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
                IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
                sInstance = new InputMethodManager(service, Looper.getMainLooper());
            }
            return sInstance;
        }
    }
} 

ii > Calendar 인 스 턴 스 가 져 오기 달력:
Calendar calendar = Calendar.getInstance();           

5, 코드
1) 게으름뱅이 식 (추천 하지 않 음)
① 개념
싱글 톤 클래스 가 메모리 에 들 어 갈 때 대상 이 존재 하지 않 습 니 다.대상 은 방법 이 호출 되 었 을 때 초기 화 되 며 대상 의 지연 호출 이 라 고도 합 니 다.이중 검사 로 잠 금 추가 (double - checked locking)
② 장면
외부 인삼 이 있어 야 대상 을 만 들 때 사용 할 수 있 습 니 다. 사용 시 스 레 드 보안 문제 에 주의 하 십시오.
③ 장단 점
장점: 굶 주 린 사람 식 의 사용 되 지 않 은 상황 에서 사례 를 만 드 는 것 을 피하 고 자원 이 용 률 이 높 으 며 getInstance () 를 실행 하지 않 습 니 다.인 스 턴 스 를 받 지 않 고 다른 정적 방법 을 실행 할 수 있 습 니 다. 단점: 게으름뱅이 식 은 하나의 스 레 드 에 문제 가 없 지만 여러 스 레 드 동료 가 방문 할 때 동료 가 여러 개의 인 스 턴 스 를 만 들 수 있 습 니 다. 그리고 이 여러 인 스 턴 스 는 같은 대상 이 아 닙 니 다. 나중에 만 든 인 스 턴 스 는 먼저 만 든 인 스 턴 스 를 덮어 쓰 지만 서로 다른 대상 을 가 져 오 는 경우 가 있 습 니 다. 해결이 문제 의 방법 은 바로 잠 금 synchonized 를 추가 하 는 것 입 니 다. 처음 불 러 올 때 빠 르 지 않 고 다 중 스 레 드 를 사용 할 때 불필요 한 동기 화 비용 이 많이 듭 니 다.
④ 실현
이중 검사 자물쇠 (이중 검사 자물쇠, DCL)
package Singleton;

/**
 *    
 * Singleton     ,       。         ,    ,          。
 *         (double-checked locking)
 * @author luo
 */
class Singleton {
    private Singleton() {
    }
    /**
     * volatile     : instance       Singleton   ,         instance  
     */
    private volatile static Singleton instance = null;
    /**
     *       
     *              ,      ,       。
     *           。
     * @return
     */
    public static Singleton getInstance() {
        if (null == instance) {// instance              synchronized (Singleton.class)     ,      
            synchronized (Singleton.class) {
                //   ,          
                if (instance == null) {
                    //     ,     ,    null,     
                    instance = new Singleton();
                }
            }
        }
        return instance;

    }

    /*
     *   
     */
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

1. Singleton 에 메모리 할당 2. Singleton 의 구조 함 수 를 호출 하여 구성원 필드 를 초기 화 합 니 다. 3. intance 대상 을 분 배 된 메모리 공간 으로 가리 키 기 (이때 intance 는 null 이 아 닙 니 다)
jdk 1.5 이후 자바 컴 파 일 러 는 무질서 하 게 실행 할 수 있 습 니 다. 따라서 실행 순 서 는 1 - 3 - 2 또는 1 - 2 - 3 일 수 있 습 니 다. 전자 가 3 을 먼저 실행 하면 다른 스 레 드 로 전환 합 니 다. instance 가 비어 있 습 니 다. 이 스 레 드 는 인 스 턴 스 를 직접 가 져 가서 오류 가 발생 합 니 다. DCL 이 실 효 됩 니 다. 해결 방법 은 SUN 공식 적 으로 알려 졌 습 니 다. instance 를 인 스 턴 스 로 정의 합 니 다.4. 567914. 그러면 됩 니 다.
2) 굶 주 린 한식 (추천)
① 개념
대상 을 초기 화 합 니 다.싱글 톤 클래스 는 메모리 에 들 어가 자마자 대상 을 불 러 옵 니 다.
② 장면
외부 참조 가 필요 없습니다.사용 이 비교적 간단 하고 게으름뱅이 보다 자주 사용 된다.
③ 장단 점
장점 1. 스 레 드 보안 2. 클래스 로 딩 과 동시에 정적 대상 을 만 들 었 습 니 다. 호출 할 때 반응 속도 가 빠 르 고 단점 자원 효율 이 높 지 않 습 니 다. getInstance () 는 영원히 실행 되 지 않 을 수 있 지만, 이러한 정적 방법 을 실행 하거나 클래스 (class. forName) 를 불 러 왔 습 니 다. 그러면 이 인 스 턴 스 는 초기 화 됩 니 다.
④ 실현
package Singleton;

public class Main {

    public static void main(String[] args) {    

        Singleton1 s11 = Singleton1.getInstance();
        Singleton1 s12 = Singleton1.getInstance();

        s11.setName("     ");
        System.out.println(s12.getName());//   s11 s12       
    }
}
package Singleton;
/**
 *    
 *       。Singleton          。
 * @author luo
 */
class Singleton1 {
    private Singleton1() {
    }
    private static Singleton1 instance = new Singleton1();
    public static Singleton1 getInstance() {
        return instance;
    }
    /*
     *   
     */
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

3) 정적 내부 클래스 (추천)
① 장면
일반적으로 굶 주 린 사람 식 을 사용 하 는데 자원 에 대해 매우 신경 을 쓰 면 정태 적 인 내부 류 를 사용 할 수 있 고 게 으 른 사람 식 과 이중 검 사 를 사용 하 는 것 을 권장 하지 않 는 다.내부 클래스 를 사용 하여 이 내부 클래스 에서 대상 인 스 턴 스 를 만 듭 니 다.이렇게 되면 응용 프로그램 에서 내부 클래스 를 사용 하지 않 으 면 JVM 은 이 단일 클래스 를 불 러 오지 않 고 단일 대상 을 만 들 지 않 아 게으름뱅이 식 지연 로드 와 스 레 드 안전 을 실현 합 니 다.
② 장단 점
장점 자원 이 용 률 이 높 고 getInstance () 를 실행 하지 않 으 면 인 스 턴 스 가 되 지 않 습 니 다. 다른 정적 방법 을 실행 할 수 있 습 니 다. 첫 번 째 로 불 러 올 때 반응 이 빠 르 지 않 습 니 다.
③ 실현
public class Singleton{
    //   ,                 
    private static class SingletonHolder{
        public static Singleton instance = new Singleton();
    }

    private Singleton(){}

    public static Singleton newInstance(){
        return SingletonHolder.instance;
    }

    public void doSomething(){
        //do something
    }
}

4) 매 거 일례
① 개념
Effective 자바 에 서 는 매 거 진 을 사용 하 는 보다 간결 하고 편리 한 사용 방식 을 추천 했다.기본 매 거 진 인 스 턴 스 의 생 성 은 스 레 드 가 안전 합 니 다. (매 거 진 클래스 를 만 드 는 사례 는 JVM 차원 에서 도 스 레 드 안전 을 보장 할 수 있 습 니 다) 따라서 스 레 드 안전 문 제 를 걱정 할 필요 가 없 기 때문에 이론 적 으로 매 거 진 클래스 를 통 해 단일 모델 을 실현 하 는 것 이 가장 간단 한 방식 입 니 다.
② 장면
스 레 드 가 안전 하고 간단 합 니 다.역 직렬 화 할 때 대상 을 다시 만 들 지 않 습 니 다.
③ 실현
public enum Singleton{
    //         ,   Singleton     
    instance;

    public void doSomething(){
        // do something ...
    }    
}

사용:
public static void main(String[] args){
   Singleton singleton = Singleton.instance;
   singleton.doSomething();
}

④ 반 서열 화
단일 대상 이 반 직렬 화 될 때 대상 을 다시 만 드 는 것 을 막 으 려 면 다음 과 같은 방법 을 추가 해 야 한다.
private Object readResolve() throws ObjectStreamException{
    return instance;
}

만약 당신 의 단일 클래스 가 다른 대상 의 상 태 를 유지 했다 면, 당신 은 그들 을 transient 의 대상 으로 만들어 야 합 니 다.그러나 매 거 진 단 례 를 들 면 JVM 은 서열 화 에 대한 보증 이 있다.역 직렬 화 시 새로운 인 스 턴 스 가 생 성 되 지 않 습 니 다.
5) 용기 모드 사용 사례
③ 개념
여러 개의 단일 모드 유형 을 하나의 통 일 된 관리 클래스 에 주입 하고 사용 할 때 key 에 따라 대응 하 는 유형의 대상 입 니 다.
② 장면
다양한 유형의 단일 사례 를 관리 하기 쉽 고 사용 할 때 통 일 된 인 터 페 이 스 를 통 해 조작 을 할 수 있 으 며 사용자 의 사용 원 가 를 낮 출 수 있 으 며 사용자 에 게 구체 적 인 실현 을 숨 기 고 결합 도 를 낮 출 수 있다.
③ 실현
public class SingletonManager{
    private static Map obMap = new hashMap();
    private SingletonManager(){}
    public static void registerService(String key, Object instance){
        if(!obMap.containKey(key)){
            obMap.put(key,instance);
        }
    }

    public static Object getService(String key){
        return obMap.get(key);
    }
}

좋은 웹페이지 즐겨찾기