본문 바로가기

자바스크립트 심화(11) 모듈패턴 만들기

by Recstasy 2019. 6. 18.

모듈은 간단하게 말해서 '부품'이다. 각종 모듈은 우리 주변에서도 쉽게 찾아볼 수 있다. 가령, 스마트폰은 카메라 모듈부터 시작해서 각종 센서 모듈로 구성된다. 그렇다면 모듈이 부품이란 것은 알겠는데 굳이 패턴을 만들어야 할 이유가 있을까? 


모듈패턴을 위해서 '전자기기 서비스센터'를 생각해보자. 만일 '삼성전자' 스마트폰이 고장나서 애플 서비스센터에 맡기면 어떻게 될까. 현대 자동차가 고장나서 벤츠 서비스센터로 가면 고칠 수 있을까? 코딩용어를 생활에 비유하면 너무 상식적인 질문이 된다.


전자기기 모듈에는 각기 브랜드 이름이 존재하듯이 프로그램을 구성하는 모듈에도 특별한 '접근'이 존재한다. 

모듈의 핵심은 조립이다. 조립은 이 모듈 저 모듈 중에서 호환되는 것을 뽑아서 붙이는 작업이다. 즉, 특정한 브랜드의 모듈은 특정 명령어를 일괄적으로 적용할 수 있어야하고, 복제품들이 똑같이 공유하는 비공개 데이터가 있어야 한다. 같은 제품의 모듈들은 아이덴티티가 같아야 한다. 


위의 질문에 답을 한다면, 전자기기의 서비스센터는 자사 브랜드 제품에 관한 모듈 시스템을 확보하고 있고, 비공개로 되어 있는 명령어와 데이터들을 공유하고 있다. 자바스크립트로 대규모 프로그램을 작성한다면, 자신이 만든 프로그램 내부의 모듈들은 비공개

데이터를 공유하고, 공통적인 명령어가 먹혀야 한다.


모듈에 관한 간단한 예시를 살펴보자.


1 『모듈패턴』

let car = (function(){


     let price = 3200;

     return {

           name : '도요타 프리우스',

           getPrice : function(){

                return price;

            },

          upgradePrice : function(){

                price += 100;

          }

     }

})();


   console.log(car.name);  //>>

   car.upgradePrice(); //>>

   car.price = 5000;

   console.log(car.price);  //>>

   console.log(car.getPrice());  //>>

   console.log(car);


위의 코드에서 ① ~ ④까지 어떠한 결과가 나올지 예상해보자. car는 즉시실행 함수이며, 지역변수 'price'와 name ~ upgradePrice라는 속성 및 메서드를 반환하고 있다. 값은 car의 name, '도요타 프리우스'가 된다. 


에서 car.upgradePrice()를 실행하면 지역변수 'price'의 값에 100이 더해진다. 그리고 car.price = 5000;명령을 넣어서 car의 속성으로 price와 값, 5000을 넣는다. 그 결과 에서 car.price값은 '5000'이 된다. car.price로 5000을 넣었기 때문이다. 그렇다면 car함수 내부의 지역변수, price값이 5000으로 바뀐걸까? 


을 실행하는 순간 왜 모듈패턴을 사용하는지 이유를 알 수 있다. car함수 내부에서 지역변수에 접근하는 메서드 'getPrice()'의 결과값은 '3300'이다. 즉, 함수 내부의 지역변수는 같은 내부의 메서드에서만 접근할 수 있다. 만일 'car'를 생성자 방식으로 만든다면 상속받는 인스턴스 역시 지역변수 price에 접근할 수 있는 채널이 내부 메서드로 한정된다. 


2 『비공개 모듈 패턴』

 let Smartphone = (function(){

       let price = 345600;

     

         function Smartphone(model){

            this.model = model

        }

         Smartphone.prototype.getPrice = function(){

              return price;

        }

         Smartphone.prototype.upgrade = function(){

              price += 50000;

      }

       return Smartphone;

  })();


    let gallaxy_s10 = new Smartphone("s10");

    let gallaxy_a80 = new Smartphone("a80");


     console.log(gallaxy_s10.model);   //>>s10

     console.log(gallaxy_s10.getPrice());  //>>345600


     gallaxy_s10.upgrade();


     console.log(gallaxy_s10.getPrice()); //>>395600

     console.log(gallaxy_a80.model); //>>a80

     console.log(gallaxy_a80.getPrice());  //345600



위의 코드에서 전체 생성자와 내부 생성자의 이름을 똑같이 맞출 필요가 없다. 아래처럼 Smartphone생성자 내부의 Smartphone()이름을 Amartphone으로 바꾸더라도 즉시실행 함수의 인자는 내부 생성자의 인자로 즉시 유입된다. 


 let Smartphone = (function(){

       let price = 345600;

     

         function Amartphone(model){

            this.model = model

        }

         Amartphone.prototype.getPrice = function(){

              return price;

       }

        Amartphone.prototype.upgrade = function(){

              price += 50000;

      }

       return Amartphone;

  })()

    let gallaxy_s10 = new Smartphone("s10");

    let gallaxy_a80 = new Smartphone("a80");


     console.log(gallaxy_s10.model);  //>>s10

     console.log(gallaxy_s10.getPrice());  //>>345600

     gallaxy_s10.upgrade();

      console.log(gallaxy_s10.getPrice());   //>>395600

     console.log(gallaxy_a80.model);    //>>a80

     console.log(gallaxy_a80.getPrice());   //345600


즉시실행 함수로 생성자를 만든다면, 위와 같이 내부 생성자(클래스)를 감출 수 있고, 특정 규약에 의해 메서드를 조절할 수 있다.


댓글

최신글 전체

이미지
제목
글쓴이
등록일