11

Niedawno poznałem wzór modułu Revealing Module i przeczytałem kilka artykułów na ten temat.Ujawniające się wadliwe modele modułów:

Wygląda na bardzo dobry wzór i chciałbym zacząć go używać w dużym projekcie, który mam. W projekcie używam: Jquery, KO, requirejs, Jquery Mobile, JayData. Wydaje mi się, że będzie dobrze pasował do KO ViewModels.

W szczególności chciałbym użyć wersji THIS.

Jedną z rzeczy, których nie mogłem znaleźć, są wady używania tego wzoru, czy to dlatego, że nie ma żadnych (trudno mi w to uwierzyć)?

Co powinienem rozważyć przed rozpoczęciem użytkowania?

+2

Sprawdź ten artykuł: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript na końcu znajduje się sekcja wady. – nemesv

+0

Definicyjny wzorzec modułu eliminuje również pewne wady za pomocą wzorca modułu i wzoru ujawniającego (takiego jak ścisłe powiązanie z instrukcją return, jak deklarowane są funkcje publiczne i prywatne, nieprzypisane przestrzenie nazw dla prywatnych i publicznych podprogramów i mieszane użycie obiektu dosłowne z instrukcją zwrotu): http://github.com/tfmontague/definitive-module-pattern – tfmontague

Odpowiedz

4

Przeczytałem artykuł, do którego @nemesv odwołał się do mnie (dzięki :)) i myślę, że jest jeszcze jedna wada, o której nie wspomniano, więc pomyślałem, że dodam ją tutaj w celach informacyjnych. Oto cytat z artykułu:

Wady

Wadą tego układu jest to, że jeśli prywatny funkcja odnosi się do funkcję publiczną, że funkcja publiczna nie może być pominięte, jeżeli jest łata niezbędny. Wynika to z faktu, że funkcja prywatna będzie nadal oznaczać implementację prywatną, a wzorzec nie ma zastosowania do publicznych użytkowników, tylko do funkcji.

Elementy obiektu publicznego, które odnoszą się do zmiennych prywatnych, są również oznaczone jako , z zastrzeżeniami opisanymi powyżej.

W związku z tym moduły utworzone za pomocą wzorca Modułu ujawniającego mogą być bardziej kruche niż te utworzone za pomocą oryginalnego wzoru modułu , dlatego należy zachować ostrożność podczas użytkowania.

A mój dodatek:

nie można korzystać z tego wzoru dziedziczenia. Na przykład:

var Obj = function(){ 
    //do some constructor stuff 
} 

var InheritingObj = function(){ 
    //do some constructor stuff 
} 

InheritingObj.prototype = new Obj(); 

InheritingObj.prototype.constructor = InheritingObj; 

Ten prosty przykład dla dziedziczenia w JS, ale podczas korzystania z Revealing Prototype Pattern trzeba to zrobić:

InheritingObj.prototype = (function(){ 
    //some prototype stuff here 
}()); 

który zastąpi ci dziedziczenie.

+0

Wygląda na to, że działa idealnie z Object.create (urlBuilder); Innym sposobem na dziedziczenie jest http://jsfiddle.net/d0n7kfmx/ co myślisz? – user2734550

13

Schemat modułu ujawniającego (RMP) tworzy obiekty, które nie zachowują się dobrze w odniesieniu do przesłonięcia. W konsekwencji obiekty wykonane za pomocą RMP nie działają dobrze jako prototypy. Jeśli więc używasz RMP do tworzenia obiektów, które będą używane w łańcuchu dziedziczenia, po prostu nie rób tego. Ten punkt widzenia jest moim własnym, w przeciwieństwie do tych zwolenników Odkrywczego Wzoru Prototypowego.

Aby zobaczyć złe dziedziczenia zachowań, przyjąć następującą przykład konstruktora URL:

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return _urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

Pomijając kwestię, dlaczego byłoby użyć RMP dla obiektu bez prywatnych składników, trzeba pamiętać, że jeśli odebrać zwrócony obiekt i zastąpić urlBase przez "http://stackoverflow.com", można oczekiwać, że zachowanie funkcji build() odpowiednio się zmieni. To nie jest, jak widać poniżej:

var builder = new rmpUrlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions" 

Kontrast zachowanie z realizacją budowniczy następujący adres URL

function urlBuilder = function(){ 
    return { 
    urlBase: "http://my.default.domain/". 
    build: function(relUrl){ return this.urlBase + relUrl;} 
    } 
} 

var builder = new urlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build()); // prints "http://stackoverflow.com/questions" 

który zachowuje się poprawnie.

Można poprawić zachowanie ujawniające moduł wzór, używając tego zakresu jak w poniższym

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return this.urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

ale raczej pokonuje cel ujawniając Module Pattern. Aby uzyskać więcej informacji, patrz mój blog zakładać http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/

-2

innych wad z ujawniając Module Wzór to:

  1. Tight sprzężenie funkcji publicznych z rachunku Return
  2. Mieszane wykorzystanie obiektu dosłowny dla funkcji publicznych oraz standalone deklaracje na prywatne

polecam korzystania ostatecznego module Wzorzec nad ujawniając module Wzór (https://github.com/tfmontague/definitive-module-pattern)

+0

Nie poleciłbym tego wzoru, ponieważ nie różni się zasadniczo od wzoru modułu odkrywczego. Ma te same niedociągnięcia w odniesieniu do nadpisania i prototypu, jak w przyjętej odpowiedzi. –

+0

Pytanie dotyczyło wad wzorca modułu ujawniającego. Nie chodziło o decyzję o użyciu wzorca modułu. – tfmontague