02 단례, 정책

8192 단어 단례

단일 모드

  • 한 종류에 하나의 실례만 있고 그의 전역 방문점을 제공한다

  • 시뮬레이션 단례 실현

  • 전통 방식:
  • 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 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);
    };
    
    var proxyCreateDiv = (function(){
      var instance;
      return function(html) {
        if(instance)
          return instance;
        return new CreateDiv(html);
      }
    })(); 

    JS의 단례 모드

  • 전통 모델에서 하나의 예시 대상은 클래스에서 만들어졌지만 JS는 클래스가 없다
  • 단일 모델 핵심으로 잡기: 전역적으로 접근할 수 있는 실례가 하나만 확보한다.JS에 더 적합한 방식으로 만들 수 있습니다
  • 명칭 공간을 사용합니다
  • 글로벌 네임스페이스를 적절히 사용합니다
  • 동적으로 이름 공간을 만듭니다
  • var MyApp = {};
      
    MyApp.namespace = function(name) {
      var parts = name.split('.'),
          current = MyApp;
      for(prop in parts) {
        if(!current[parts[prop]])
          current[parts[prop]] = {};
        current = current[parts[prop]];
      }
    }
  • 폐쇄 폐쇄 사유 변수를 사용합니다
  • var user = (function() {
      var _name = 'jinks',
          _age = 23;
      return {  // 
        getUserInfo: function() {
          return _name + ' ' + _age;
        }
      }
    })();

    불활성

  • 즉 필요할 때만 만들어진 단례 대상 실례입니다
  • 창설 실례 대상과 관리 단례를 분리하는 것을 최적화한다
  • /**
     *  | | div
     */
    var getSingle = function (fn) {
      var result;
      return function() {
        return result || (result = fn.apply(this, arguments))  
      }
    };
    
    var createDiv = function(name, id) {
      var div = document.createElement('div');
      div.innerHTML = name;
      div.id = id;
      div.style.display = 'none';
      document.body.appendChild(div);
      return div;
    };
    
    var divChange = function(fn,name,id) {
      var div = fn(name,id);
      var display = div.style.display;
      div.style.display = display === 'none' ? 'block' : 'none';
    };
    
    divElem = {
      div1: getSingle(createDiv),
      div2: getSingle(createDiv)
    };
    
    document.getElementById('div1Btn').onclick = function () {
      divChange(divElem.div1,'div1','div1');
    };
    document.getElementById('div2Btn').onclick = function () {
      divChange(divElem.div2,'div2','div2');
    };
  • 타성 단례를 이용하여one() 귀속 이벤트의 효과를 실현할 수 있다
  • var bindEvent = getSingle(function() {
      document.getElementById('click').onclick = function() {
        alert('click');
      }
      return true;
    });
    
    bindEvent();  // 
    bindEvent();
    bindEvent();

    정책 모드

  • 일련의 알고리즘을 정의하고 봉인하여 서로 바꿀 수 있도록 한다
  • 함수에 대한
  • 비교적 방대하다: 여러 개를 포함한다if-slse ;
  • 탄력성 부족: 판단을 수정하려면 내부에 깊이 들어가야 하며 개방-폐쇄원칙에 위반된다
  • 복용성이 떨어진다
  • 정책 모델을 바탕으로 하는 프로그램은 적어도 두 부분으로 구성된다
  • 전략류: 구체적인 알고리즘을 봉인하고 구체적인 계산 과정을 책임진다
  • 환경류: 요청을 받은 후 특정한 전략류에 의뢰한다

  • 시뮬레이션 전략 실현

    /**
     *  
     */ 
    // 
    var performancsA = function () {}
    performancsA.prototype.calculate = function(salary) {
      return salary * 3;
    };
    var performancsB = function () {}
    performancsB.prototype.calculate = function(salary) {
      return salary * 4;
    };
    // 
    var Bonus = function() {
      this.salary = null;
      this.strategy = null;
    };
    Bonus.prototype.setSalary = function(salary) {
      this.salary = salary;
    };
    Bonus.prototype.setStrategy = function(strategy) {
      this.strategy = strategy;
    };
    Bonus.prototype.getBouns = function() {
      return this.strategy.calculate(this.salary);
    };
    
    
    var bouns = new Bonus;
    bouns.setSalary(10000);
    bouns.setStrategy(new performancsA);
    bouns.getBouns();//30000;
    bouns.setStrategy(new performancsB);
    bouns.getBouns();//40000;

    JS의 정책 모드

  • JS의 함수도 대상이다
  • var strategies = {
     'A': function (salary) {
       return salary * 3; 
     },
     'B': function (salary) {
       return salary * 4;
     }
    };
    
    var calculateBonus = function(level, salary) {
      return strategies[level](salary);
    };
    
    calculateBonus('A', 10000);
    calculateBonus('B', 10000);

    애니메이션 부드럽게 하기

    // 
      var tween = {
        linear: function(t, b, c, d) { // , , , 
          return c * t / d + b;
        },
        easeIn: function(t, b, c, d) {
          return c * (t /= d) * t + b;
        },
        strongEaseIn: function(t, b ,c ,d) {
          return c * (t /= d) * t * t * t * t + b;
        },
        strongEaseOut: function(t, b, c, d) {
          return c * ((t = t / d - 1) * t * t * t * t * t + 1) + b;
        },
        sineaseIn: function(t, b, c, d) {
          return c * (t /= d) * t * t + b;
        },
        sineaseOut: function(t, b ,c ,d) {
          return c * ((t = t /d - 1) * t * t + 1) + b;
        },
    
      };
    
      var Animate = function (elem) {
        this.elem = elem;
        this.startTime = 0;
        this.startPos = 0;
        this.endPos = 0;
        this.properrtName = null;
        this.easing = null;
        this.duration = null;
      };
    
      Animate.prototype.start = function (properrtName, endPos, duration, easing) {
        var self = this;
        self.startTime = +new Date;
        self.startPos = self.elem.getBoundingClientRect()[properrtName];
        self.properrtName = properrtName;
        self.endPos = endPos;
        self.duration = duration;
        self.easing = tween[easing];
    
        var timeId = setInterval(function() {
          if(self.step() === false)
            clearInterval(timeId);
        }, 20);
      };
      Animate.prototype.step = function() {
        var t = +new Date;
        if(t >= this.startTime + this.duration) {
          this.update(this.endPos);
          return false;
        }
        var pos = this.easing(t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration);
        this.update(pos);
      };
    
      Animate.prototype.update = function(pos) {
        this.elem.style[this.properrtName] = pos + 'px';
      }
    
      var div = document.getElementById('div');
      var animate = new Animate(div);
    
      animate.start('left', 500, 1000, 'sineaseIn');

    양식 검증 구현

    // 
    var strategies = {
      isNonEmpty: function(value, errMsg) {
        if(value === '')
          return errMsg;
      },
      minLength: function(value, length, errMsg) {
        if(value.length < length)
          return errMsg;
      }
    };
    //valiator 
    var Valiator = function() {
      this.cache = [];
    };
    Valiator.prototype.add = function(elem, rules) {
      var self = this;
      for(var i = 0, rule; rule = rules[i++];) {
        (function(rules) {
          var strategyAry = rule.strategy.split(':');
          var errMsg = rule.errMsg;
          self.cache.push(function() {
            var strategy = strategyAry.shift();
            strategyAry.unshift(elem.value);
            strategyAry.push(errMsg);
            return strategies[strategy].apply(elem, strategyAry);
          });
        })(rule);
      }
    };
    Valiator.prototype.start = function() {
      for(var i = 0, valiatorFn; valiatorFn = this.cache[i++];) {
        var errMsg = valiatorFn();
        if(errMsg)
          return errMsg;
      }
    };
    // 
    var registerForm = document.getElementById('registerForm');
    var valiatorFn = function() {
      var valiator = new Valiator;
      valiator.add(registerForm.username, [{
        strategy: 'isNonEmpty',
        errMsg: ' '
      }, {
        strategy: 'minLength:10',
        errMsg: ' 10 '
      }]);
      valiator.add(registerForm.password, [{
        strategy: 'minLength:6',
        errMsg: ' 6 '
      }]);
      var errMsg = valiator.start();
      return errMsg;
    };
    
    registerForm.onsubmit = function() {
      var errMsg = valiatorFn();
      if(errMsg) {
        alert(errMsg);
        return false;
      }
      return true;
    };

    이점

  • 조합, 위탁, 다태 등을 이용하여 다중 조건 선택을 효과적으로 피한다
  • 개방 - 폐쇄 원칙에 대한 지원
  • 중용성이 높다
  • 조합과 위탁 방식으로 상속을 대체한다
  • JS에서 함수는 일등 공민이기 때문에 전략류는 함수에 의해 대체되고 은밀하게 전략 모델을 사용한다
  • 좋은 웹페이지 즐겨찾기