JavaScript 설계 모드(일례 모드)

12803 단어
단례 모델은 간단하지만 매우 실용적인 모델이다. 특히 타성 단례 기술은 적당한 때만 대상을 만들고 유일한 것만 만든다.다음은 우리가 단례 모델의 용법을 점차적으로 이해하자.

1. 간략한 단례 모드:

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( 'sven1' ); 
var b = Singleton.getInstance( 'sven2' );
alert ( 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 Singleton( name );
    }
    return instance; 
  }
})();
var a = Singleton.getInstance( 'sven1' ); 
var b = Singleton.getInstance( 'sven2' );
alert ( a === b ); // true

이상은 간단한'불투명'단례 모델이지만 실제 프로젝트에서의 의미는 크지 않다.

2. 투명한 단일 예제 모드:

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' );

alert ( a === b ); // true

이 코드에서 CreateDiv의 구조 함수는 실제적으로 두 가지 일을 책임진다. 첫째는 대상을 만드는 것과 초기화 init 방법을 실행하는 것이다. 둘째는 하나의 대상만 보장하는 것이다.
비록 우리는 아직'단일직책원칙'이라는 개념을 접촉한 적이 없지만, 명확한 것은 이것은 좋지 않은 방법이다. 적어도 이 구조 함수는 보기에 매우 이상하다.
만약에 우리가 언젠가 이 클래스를 이용하여 페이지에 수천수만의div를 만들어야 한다고 가정하자. 즉, 이 클래스를 하나의 클래스에서 하나의 일반적인 여러 개의 실례를 만들 수 있는 클래스로 바꾸려면 CreateDiv 구조 함수를 고쳐서 유일한 대상을 만드는 것을 제어하는 부분을 제거해야 한다. 이런 수정은 우리에게 불필요한 고민을 가져다 줄 것이다.

3: 에이전트로 단일 모드 구현:

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 );

프록시 클래스를 도입하는 방식을 통해 우리는 하나의 사례 모델의 작성을 완성했다. 이전과 달리 현재 우리는 관리 사례의 논리를 프록시 singleton Create Div로 옮겼다.
이렇게 되면 Create Div는 일반적인 종류가 되고 proxysingleton Create Div와 조합하면 단일 모드의 효과를 얻을 수 있다.

4. js의 단례 모드:


앞에서 언급한 몇 가지 단례 모델의 실현은 전통적인 대상 언어에서의 실현에 가깝고 단례 대상은'클래스'에서 만들어졌다.클래스 중심의 언어에서 이것은 매우 자연스러운 방법이다.예를 들어 자바에서 어떤 대상이 필요하다면 먼저 클래스를 정의해야 한다. 대상은 항상 클래스에서 만들어진다.
그러나 자바스크립트는 사실 무류(class-free) 언어이다. 그렇기 때문에 단례 모델의 개념을 생략하는 것은 의미가 없다.JavaScript에서 객체를 만드는 방법은 매우 간단합니다. "유일한"객체만 필요하면 왜 클래스를 먼저 만들어야 합니까?이것은 면옷을 입고 목욕하는 것과 다름없다. 전통적인 단례 모델은 자바스크립트에서 적용되지 않는다.단일 모드의 핵심은 하나의 실례만 확보하고 전역적인 접근을 제공하는 것이다.
전역 변수는 단일 모드가 아니지만 자바스크립트 개발에서 우리는 전역 변수를 단일 모드로 자주 사용한다.예: var a = {};이런 방식으로 대상 a를 만들 때, 대상 a는 확실히 유일무이하다.만약에 a 변수가 전역 작용역에 성명된다면 우리는 코드의 어느 위치에서든 이 변수를 사용할 수 있습니다. 전역 변수가 전역 접근에 제공되는 것은 당연한 것입니다.이렇게 하면 단례 모델의 두 가지 조건을 만족시킬 수 있다.그러나 전체 변수에 문제가 많아 명명 공간 오염을 일으키기 쉽다.두 가지 방법으로 변수의 전체 오염을 피할 수 있다.
1. 네임스페이스 사용: 네임스페이스를 적절하게 사용하면 전역 변수를 차단하지 않지만 전역 변수의 수를 줄일 수 있다.
var namespace1 = { 
    a: function(){ 
        alert (1);
    },
    b: function(){
        alert (2); 
    }
};    

2、폐쇄 봉인 사유 변수 사용
var user = (function(){ 
  var __name = 'sven',
    __age = 29;
  return {
    getUserInfo: function(){
      return __name + '-' + __age; 
    }
  } 
})();

5. 불활성 사례:


타성 단례는 필요할 때 대상을 만드는 실례를 가리킨다.타성 단례는 단례 모델의 중점으로 이런 기술은 실제 개발에서 매우 유용하다.
우리는 관리 사례의 논리를 원래의 코드에서 추출할 수 있다.
var getSingle = function( fn ){ 
  var result;
  return function(){
    return result || ( result = fn .apply(this, arguments ) );
  } 
};

로그인 플러그인을 만드는 방법을 매개 변수 fn 형식으로 getSingle에 전송합니다. 우리는createLoginLayer뿐만 아니라createScript,createIframe,createXhr 등도 전송할 수 있습니다.다음에 getSingle을 새로운 함수로 되돌려주고 변수result로 fn의 계산 결과를 저장합니다.result 변수는 패키지에 있기 때문에 영원히 삭제되지 않습니다.미래의 요청에서,result가 값을 부여했다면, 이 값을 되돌려줍니다.

var
createLoginLayer = function(){ var div = document.createElement( 'div' ); div.innerHTML = ' '; div.style.display = 'none'; document.body.appendChild( div ); return div; }; var createSingleLoginLayer = getSingle(createLoginLayer); document.getElementById( 'loginBtn' ).onclick = function(){ var loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block'; }; iframe: var createSingleIframe = getSingle( function(){ var iframe = document.createElement ( 'iframe' ); document.body.appendChild( iframe ); return iframe; }); document.getElementById( 'loginBtn' ).onclick = function(){ var loginLayer = createSingleIframe(); loginLayer.src = 'http://baidu.com'; };

이 예에서 우리는 실례 대상을 만드는 직책과 관리 단례의 직책을 각각 두 가지 방법에 두었다. 이 두 가지 방법은 독립적으로 변화하여 서로 영향을 주지 않고 연결될 때 유일한 실례 대상을 만드는 기능을 완성했다.

좋은 웹페이지 즐겨찾기