programing

자바 스크립트 디자인 패턴 : 모듈 패턴과 공개 모듈 패턴의 차이점?

projobs 2021. 1. 14. 08:00
반응형

자바 스크립트 디자인 패턴 : 모듈 패턴과 공개 모듈 패턴의 차이점?


최근에 Learning JavaScript Design Patterns 라는 책을 읽고 있습니다. 내가 이해하지 못하는 것은 모듈 패턴과 공개 모듈 패턴의 차이입니다. 나는 그들이 같은 것이라고 느낍니다. 누구든지 예를 들어 줄 수 있습니까?


모듈 패턴을 구현하는 방법에는 세 가지 이상이 있지만 공개 모듈 패턴은 공식 이름을 가진 유일한 모듈 패턴 하위 항목입니다.

기본 모듈 패턴

모듈 패턴은 다음을 충족해야합니다.

  • 비공개 회원은 폐쇄에 살고 있습니다.
  • 공용 멤버는 반환 개체에 노출됩니다.

그러나이 정의에는 많은 모호성이 있습니다. 모호성을 다르게 해결하면 모듈 패턴의 변형을 얻을 수 있습니다.

드러나는 모듈 패턴

공개 모듈 패턴은 모듈 패턴 변형 중 가장 유명하고 가장 인기가 있습니다. 다음과 같은 다른 대안에 비해 많은 장점이 있습니다.

  • 함수 본문을 변경하지 않고 공용 함수의 이름을 바꿉니다.
  • 함수 본문을 변경하지 않고 한 줄을 수정하여 멤버를 공용에서 개인으로 또는 그 반대로 변경합니다.

RMP는 원본에 추가 된 세 가지 추가 조건을 충족합니다.

  • 공개 또는 비공개 여부에 관계없이 모든 구성원은 클로저에 정의됩니다.
  • 반환 객체는 함수 정의가없는 객체 리터럴입니다. 모든 오른쪽 표현식은 클로저 변수입니다.
  • 모든 참조는 반환 객체가 아닌 클로저 변수를 통해 이루어집니다.

다음 예는 사용 방법을 보여줍니다.

var welcomeModule = (function(){
  var name = "John";
  var hello = function(){ console.log("Hello, " + name + "!");}
  var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
  return {
    name: name,
    sayHello: hello,
    sayWelcome: welcome
  }
})();

make namesayHelloprivate 을 원하면 반환 객체에서 적절한 줄을 주석 처리하면됩니다.

var welcomeModule = (function(){
  var name = "John";
  var hello = function(){ console.log("Hello, " + name + "!");}
  var welcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
  return {
    //name: name,
    //sayHello: hello,
    sayWelcome: welcome
  }
})();

객체 리터럴이있는 모듈 패턴

이것은 아마도 모듈 패턴의 가장 오래된 변형 일 것입니다. RMP와 달리이 변종에 대한 공식적인 이름은 없습니다.

원본 외에도 다음 조건을 충족합니다.

  • 비공개 멤버는 클로저에 정의됩니다.
  • 공용 멤버는 반환 개체 리터럴에 정의됩니다.
  • 공개 멤버에 대한 참조는 this가능할 때마다 를 통해 제공 됩니다.

다음 예제에서는 RMP와 달리 함수 정의가 실제로 반환 개체 리터럴에 있고 멤버에 대한 참조가 this.

var welcomeModule = (function(){
  return {
    name: "John",
    sayHello: function(){ console.log("Hello, " + this.name + "!");}
    sayWelcome: function() { console.log( this.hello() + " Welcome to StackOverflow!");}
  }
})();

RMP unlke, 수 있도록하기 위해주의 namesayHello개인을 가리키는 참조 namesayHello다양한 함수 본문의 정의에도이 변경 될 수 있습니다.

var welcomeModule = (function(){
  var name: "John";
  var sayHello = function(){ console.log("Hello, " + name + "!");};
  return {
    //name: "John",
    //sayHello: function(){ console.log("Hello, " + this.name + "!");}
    sayWelcome: function() { console.log( hello() + " Welcome to StackOverflow!");}
  }
})();

반환 객체 스텁이있는 모듈 패턴

이 변종에는 공식 이름도 없습니다.

원본 외에도 다음 조건을 충족합니다.

  • 빈 반환 객체 스텁은 처음에 정의됩니다.
  • 비공개 멤버는 클로저에 정의됩니다.
  • 공용 멤버는 스텁의 멤버로 정의됩니다.
  • 공용 멤버에 대한 참조는 스텁 개체를 통해 이루어집니다.

이전 예제를 사용하면 공용 멤버가 스텁 개체에 직접 추가되는 것을 볼 수 있습니다.

var welcomeModule = (function(){
  var stub = {};
  stub.name = "John";
  stub.sayHello = function(){ console.log("Hello, " + stub.name + "!");}
  stub.sayWelcome = function() { console.log( stub.hello() + " Welcome to StackOverflow!");}
  return stub;
})();

이전 namesayHello같이 만들고 비공개하려면 이제 비공개 멤버에 대한 참조를 변경해야합니다.

var welcomeModule = (function(){
  var stub = {};
  var name = "John";
  var sayHello = function(){ console.log("Hello, " + name + "!");}

  stub.sayWelcome = function() { console.log( hello() + " Welcome to StackOverflow!");}
  return stub;
})();

요약

The differences between the Revealing Module Pattern and the other variants of the Module Pattern is primarily in how public members are referenced. As a result, RMP is much easier to use and modify, which accounts for its popularity. However, these advantages come at a great cost (in my opinion), which Addy Osmani alludes to in his post on the Revealing Module Pattern,

A disadvantage of this pattern is that if a private function refers to a public function, that public function can't be overridden if a patch is necessary. This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions.

Public object members which refer to private variables are also subject to the no-patch rule notes above.

As a result of this, modules created with the Revealing Module pattern may be more fragile than those created with the original Module pattern, so care should be taken during usage.

and which I've talked about in some other posts.


Short answer, In Module pattern we define functions in returning object.

In Revealing Module pattern, we define functions in closure area and only use variable names in returning object.

Doing this simplifies the code and has lot of other advantages


Just try to do something based on top comment answer. May be it is safer if call private function by passing this to it, so private function could reference public function with this variable.

I created a revealing module pattern with following code.

var HTMLChanger = (function () {
    var privateFunc = function () {
        this.sayHello();
    }

    var hello = function () {
        console.log('say Hello');
    }
    var callPrivate = function () {
        privateFunc.call(this);
    }


    return {
        sayHello: hello,
        callPrivate: callPrivate
    };
})();

HTMLChanger.callPrivate();
//say Hello

HTMLChanger.sayHello = function() { console.log('say Hi!') };

HTMLChanger.callPrivate();
//say Hi!

As you can see we can override public member.

ReferenceURL : https://stackoverflow.com/questions/22906662/javascript-design-pattern-difference-between-module-pattern-and-revealing-modul

반응형