패턴

2017. 6. 4. 15:57Dev/javascript

반응형


패턴의 필요성


직관은 주로 지난 경험에 기반을 둔다. 훌륭한 개발자는 다양한 경험을 통해서 상황에 맞는 기법을 적절히 구사한다.

// 시간에 따라 진화한 코드

ix=0;
the_test:
if (ix >- myArray.length) {
  goto then_end;
}
doSomething(myArray[ix]);
ix = ix + 1;
goto the_test; // 자바스크립트에 goto 문이 있다고 치자.
the_end:

// 위 코드보다 개선된 코드
for (ix=0; ix<myArray.length; ++ix;){
  dosomething(myArray[ix]);
}

// 위 코드보다 개선된 코드
myarray.foreach(dosomething);

폭 넓은 어휘력을 소유한 개발자가 더 우아한 코드를 작성할 수 있다.


기초 개념만으로 달여낸 코드가 가장 간단하고 이해하기 쉽다는 말은 미신이다. 어휘력이 떨어지면 외려 장황하고 비비 꼬인 프로그램으로 변질되기 쉽다.



모듈 패턴

모듈 패턴은 일반적인 자바스크립트 프로젝트에서는 잘 안쓰이지만, 서버 개발을 하거나 라이브러리, 또는 API 등을 개발할 때 유용하게 사용할 수 있다.

하나의 대표 글로벌 변수 안에 여러 함수를 두는 것이 모듈 패턴의 기본이다. jquery의 $ 변수가 대표적인 예다.

var myLibrary = (function(window) {
  var myLibrary = { ... };
  return myLibrary;
}(window));


이벤트 델리케이션 패턴

다수의 HTML에 이벤트를 걸어야할 때, 그리고 활발한 이벤트 처리가 필요할 때 구성하면 좋다. HTML DOM 이벤트가 진행되는 방식을 이용한 패턴이다. 이벤트 방식에는 버블링과 캡처링이 있다. DOM의 모든 요소에 이벤트 리스너를 장착하기 보다 이벤트 방식을 이용해서 효율적으로 이벤트 리스너를 장착하는 식.

버블링 : 자식부터 부모까지(eventListener : default이며 false)

캡처링 : 부모 부터 자식까지(eventListener : true)

var wrapper = document.getElementById("tableWrapper");
  wrapper.addEventListener("click", function () {
    if (this.id && this.id.indexOf("cell") > -1 {
      alert(this.innerHTML);
    }
  }, true);
}();

이벤트 전파를 중단하고 싶다면 event.stopPropagation() 함수를 호출한다.



프락시 패턴

하나의 객체가 프락시 역할을 수행하여 상황에 따라 다른 객체에접근하게 해주거나 다른 함수를 호출하게 해주는 패턴이다. 예를 들어 객체 하나에 필요한 함수들을 정의해 놓고 함수이름을 DOM 요소의 id와 동일하게 정의하여 DOM요소의 이벤트에 따라 함수를 호출하는 식이다.

var divControlPanel = document.getElementById("controlPanel"),
    videoBunny = document.getElementById("videoBunny"),
    proxyClickEventHandler = {
      "play": function () {
         videoBunny.play();
       },
    };

divControlPanel.addEventListener("click", function (e) {
  var target = e.target || e.srcElement;
  if (proxyClickEventHandler.hasOwnProperty(target.id)) {
    proxyClickEventHandler[target.id].call();
  }
}, true);

프락시 패턴을 활용하면 캐시 기능을 구현할 수 있다.

proxyClickEventHandler = (function () {
    var cache = {};
    return function (command) {
        var video;
        if (controlVideo.hasOwnProperty(command)) {
            // cache에 있을 경우 cache에서 꺼낸다.
            if (cache.hasOwnProperty(selectControlVideo.value)) {
                video = cache[selectControlVideo.value];
            } else { // cache에 없을 경우 cache에 담는다.
                video = controlVideo.getVideoById(selectControlVideo.value);
                cache[selectControlVideo.value] = video;
            }
            controlVideo[command].call(this, video);
        }
    };
}());





반응형