-- 단일 모델

7630 단어
자세 한 개인 블 로그:https://shengchangwei.github.io/js-shejimoshi-danli/
원래 디자인 모델 만 들 어 봤 을 뿐 그 정 체 를 몰 랐 다. 오늘 드디어 디자인 모델 학습 의 전당 에 들 어 섰 다. 생각해 보 니 조금 흥분 되 었 다.
1. 정의
단일 모드: 하나의 인 스 턴 스 만 있 고 전체 방문 점 을 제공 합 니 다.(이 말 은 얼마나 이해 할 수 있 는 지, 완전한 장 을 배 워 서 품 을 얻 을 수 있다).
단일 모드 의 핵심 은 하나의 인 스 턴 스 만 확보 하고 전체 방문 을 제공 하 는 것 이다.
2. 단일 사례 모델 실현 (간단)
표준 적 인 단일 예 모드 를 실현 하려 면 복잡 하지 않 습 니 다. 하나의 변수 로 현재 특정한 클래스 에 대상 을 만 들 었 는 지 여 부 를 표시 하 는 것 이 아 닙 니 다. 만약 그렇다면 다음 에 이러한 인 스 턴 스 를 가 져 올 때 이전에 만 든 대상 으로 돌아 갑 니 다.코드 는 다음 과 같 습 니 다:
//     
var Singleton = function(name) {
    this.name = name;
    this.instance = null;
};
//     
Singleton.prototype.getName = function() {
    alert(this.name);
}
Singleton.getInstance = function(name) {
    if(!this.instance) {
        this.instance = new Singleton(name);
    }
    return this.instance;
};

var a = Singleton.getInstance('a');
var b = singleton.getInstance('b');
console.log(a === b); // true

/**  **/
var Singleton = function(name) {
    this.name = name;
}
Singleton.prototype.getName = function() {
    alert(this.name);
}
Singleton.getInstance = (function() {
    var instance = null;
    return function (name) {
        if(!instance) {
            instance = new Sinleton(name);
        }
        return instance;
    }
})();

단점: 이런 방식 은 상대 적 으로 간단 하지만 문제 가 있 습 니 다. 바로 이러한 '불투명 성' 을 증가 시 켰 습 니 다. Singleton 류 의 사용자 들 은 이것 이 하나의 사례 류 라 는 것 을 알 아야 합 니 다. 예전 에 new XXX 방식 으로 대상 을 얻 었 던 것 과 달리 Singleton. getInstance 를 사용 하여 대상 을 얻 어야 합 니 다.
3. 투명 한 단일 모드
현재 우리 의 목 표 는 '투명' 한 단일 클래스 를 실현 하 는 것 입 니 다. 사용자 가 이 클래스 에서 대상 을 만 들 때 다른 모든 일반 클래스 를 사용 할 수 있 습 니 다.아래 의 예 에서 저 희 는 CreateDiv 단일 예 류 를 사용 할 것 입 니 다. 그 역할 은 페이지 에서 유일한 div 노드 를 만 드 는 것 입 니 다. 코드 는 다음 과 같 습 니 다.
var CreateDiv = (function() {
    var instance;
    var CreateDiv = function(html) {
        if(instance) {
            return instance;
        }
        this.html = html;
        this.init();
        return instance = this;
    }
    CreateDiv.prototype.init = function() {
        var div = document.createElement('div');
        div.innerHTML = this.html;
        document.body.appendChild(div);
    };
    return CreateDiv;
})();

//    
var a = new CreateDiv('sven1');
var b = new CreateDiv('sven2');
console.log(a === b); // true

단점: 이 코드 에서 CreateDiv 의 구조 함 수 는 실제로 두 가지 일 을 맡 았 다.첫 번 째 는 대상 을 만 들 고 init 를 초기 화 하 는 방법 이 며, 두 번 째 는 대상 이 하나 밖 에 없다 는 것 을 보증 합 니 다.비록 우 리 는 아직 '단일 직책 원칙' 의 개념 을 접 한 적 이 없 지만 명확 한 것 은 이것 은 좋 지 않 은 방법 이다. 적어도 이 구조 함수 가 이상 하 게 보인다.
4. 대리 로 단일 사례 모델 실현
지금 우 리 는 대리 류 를 도입 하 는 방식 을 통 해 위 에서 언급 한 문 제 를 해결한다.
var CreateDiv = function(html) {
    this.html = html;
    this.init();
}
CreateDiv.prototype.init = function() {
    var div = document.createElement('div');
    div.innerHTML = this.html;
    document.body.appendChild(div)
}

//          ProxySingletonCreateDiv
var ProxySingletonCreateDiv = (function(){
    var instance;
    return function(html){
        if(!instance) {
            instance = new CreateDiv(html);
        }
        return instance;
    }
})();
 
 var a = new ProxySingletonCreateDiv('sven1');
 var b = new ProxySingletonCreateDiv('sven2');

 //     
 console.log(a === b);

5. JavaScript 의 단일 예 모드
앞에서 언급 한 몇 가지 단일 모델 의 실현 은 전통 적 인 대상 언어 에서 의 실현 에 가 깝 고 단일 대상 은 '클래스' 에서 만들어 진 것 이다.유형 중심의 언어 에서 이것 은 매우 자 연 스 러 운 방법 이다.예 를 들 어 자바 에서 대상 이 필요 하 다 면 먼저 클래스 를 정의 해 야 합 니 다. 대상 은 항상 클래스 에서 만들어 집 니 다.그러나 자바 스 크 립 트 는 무 류 (class - free) 언어 이기 때문에 하나의 사례 모델 을 생 성 하 는 개념 은 의미 가 없다.자 바스 크 립 트 에서 대상 을 만 드 는 방법 은 매우 간단 합 니 다. '유일한' 대상 만 필요 한데 왜 '클래스' 를 먼저 만 듭 니까?이 는 솜옷 을 입고 목욕 하 는 것 과 다름없다. 전통 적 인 단일 모델 은 자바 스 크 립 트 에 적용 되 지 않 는 다.
단일 모드 의 핵심 은 하나의 인 스 턴 스 만 확보 하고 전체 방문 을 제공 하 는 것 이다.
전역 변 수 는 단일 모드 가 아니 지만 자바 스 크 립 트 개발 에 서 는 전역 변 수 를 단일 사례 로 사용 합 니 다.그러나 전역 변 수 는 전역 오염 을 초래 할 수 있다.
다음 과 같은 몇 가지 방식 은 전체 변수 가 가 져 온 명명 오염 을 상대 적 으로 낮 출 수 있다.
1. 네 임 스페이스 사용
var namespace1 = { 
    a: function(){ 
        alert (1); 
    }, 
    b: function(){ 
        alert (2); 
    } 
};

//           
var MyApp = {};
MyApp.namespace = function( name ){ 
    var parts = name.split( '.' ); 
    var current = MyApp; 
    for ( var i in parts ){ 
        if ( !current[ parts[ i ] ] ){ 
            current[ parts[ i ] ] = {}; 
        } 
        current = current[ parts[ i ] ];
    } 
};
MyApp.namespace( 'event' ); 
MyApp.namespace( 'dom.style' ); 
console.dir( MyApp ); 
//        :
 var MyApp = { 
    event: {}, 
    dom: { 
        style: {} 
    }
 };

2. 패키지 포장 개인 변수 사용
var user = (function() {
    var _name = 'sven',
    _age = 29;
    return {
        getUserInfo: function() {
            return _name + '-' + _age;
        }
    }
})

6. 타성 사례
타성 단 예 는 필요 할 때 만 대상 인 스 턴 스 를 만 드 는 것 을 말한다.(하나의 예 는 인 스 턴 스 를 만 드 는 것 입 니 다. 중복 만 들 지 않 고 하나의 인 스 턴 스 만 만 들 수 있 습 니 다)
var createLoginLayer = (function() {
    var div;
    return function() {
        if(!div) {
            div = document.createElement('div');
            div.innerHTML = '      ';
            div.style.display = 'none';
            document.body.appendChild(div);
        }
        return div
    }
})();
document.getElementById('loginBtn').onclick = function() {
    var loginLayer = createLoginLayer();
    loginLayer.style.display = 'block';
}

단점:
  • 이 코드 는 여전히 단일 직책 원칙 을 위반 한 것 으로 창설 대상 과 관리 사례 의 논 리 는 모두 createLogin Layer 대상 내부 에 놓 여 있다
  • 우리 가 iframe 을 만 들 면 div 를 iframe
  • 로 바 꿔 야 합 니 다.
    7. 유 니 버 설 단일 모드
    //         
    var getSingle = function(fn) {
        var result;
        return function() {
            return result || (result = fn.apply(this, arguments));
        }
    }
    //         
    var createSingleframe = getSingle(function() {
        var iframe = document.createElement('iframe');
        document.body.appendChild(iframe);
        return iframe;
    })
    
    //            
    document.getElementById('loginBtn').onclick = function() {
        var loginLayer = createSingleIframe();
        loginLayer.src = 'http://shengchangwei.github.io'
    }

    이 예 에서 대상 을 만 드 는 직책 과 관리 사례 의 직책 은 각각 두 가지 방법 에 놓 여 있다. 이 두 가지 방법 은 독립 적 으로 변화 하고 서로 영향 을 주지 않 으 며 연결 할 때 유일한 인 스 턴 스 대상 을 만 드 는 기능 을 완성 했다.
    이러한 단일 모드 의 용 도 는 생 성 대상 만 있 는 것 이 아 닙 니 다. 예 를 들 어 우 리 는 보통 페이지 의 목록 을 렌 더 링 한 다음 에 이 목록 에 click 이 벤트 를 연결 해 야 합 니 다. ajax 동적 으로 목록 에 데 이 터 를 추가 하 는 경우 이벤트 대 리 를 사용 하 는 전제 에서 click 이 벤트 는 실제 적 으로 첫 번 째 렌 더 링 목록 에 한 번 만 연결 되 어야 합 니 다.그러나 우 리 는 현재 가 첫 번 째 렌 더 링 목록 인지 판단 하고 싶 지 않 습 니 다. jQuery 의 도움 을 받 으 면 노드 에 원 이 벤트 를 연결 하 는 것 을 선택 합 니 다.
    var bindEvent = function(){ 
        $( 'div' ).one( 'click', function(){ 
        alert ( 'click' );  }); 
    }; 
    var render = function(){ 
        console.log( '      ' ); 
        bindEvent(); 
    }; 
    render();
    render(); 
    render();

    getSingle 함 수 를 이용 하면 같은 효 과 를 얻 을 수 있 습 니 다.코드 는 다음 과 같 습 니 다:
    var bindEvent = getSingle(function(){ 
        document.getElementById( 'div1' ).onclick = function(){ 
        alert ( 'click' ); 
     } 
        return true; 
    }); 
    var render = function(){ 
        console.log( '      ' ); 
        bindEvent(); 
    }; 
    render(); 
    render(); 
    render();

    작은 매듭
    javascript 에서 단일 모드 를 실현 하려 면 패 킷 을 닫 는 것 이 불가피 합 니 다. 패 킷 을 닫 는 것 은 하나의 예 를 만 들 때 이미 만 든 인 스 턴 스 를 저장 하 는 것 입 니 다. 다시 만 들 필요 가 없습니다.

    좋은 웹페이지 즐겨찾기