Das Modulmuster wurde ursprünglich als eine Möglichkeit definiert, in der konventionellen Softwareentwicklung sowohl eine private als auch eine öffentliche Kapselung für Klassen bereitzustellen.
Bei der Arbeit mit dem Modulmuster kann es nützlich sein, eine einfache Vorlage zu definieren, die wir für den Einstieg verwenden. Hier ist eine, die Namensabstände, öffentliche und private Variablen abdeckt.
In JavaScript wird das Modul-Muster verwendet, um das Konzept der Klassen weiter zu emulieren, so dass wir in der Lage sind, sowohl öffentliche/private Methoden als auch Variablen in ein einziges Objekt einzubinden und so bestimmte Teile vom globalen Bereich abzuschirmen. Dadurch verringert sich die Wahrscheinlichkeit, dass unsere Funktionsnamen mit anderen Funktionen in Konflikt geraten, die in zusätzlichen Skripten auf der Seite definiert sind.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
Vorteile
Warum ist das Modulmuster eine gute Wahl? Zunächst einmal ist es für Entwickler, die aus einem objektorientierten Hintergrund kommen, viel übersichtlicher als die Idee einer echten Kapselung, zumindest aus der Sicht von JavaScript.
Zweitens unterstützt es private Daten - im Modulmuster können also öffentliche Teile unseres Codes die privaten Teile berühren, aber die Außenwelt kann die privaten Teile der Klasse nicht berühren.
Benachteiligungen
Der Nachteil des Modulmusters besteht darin, dass wir, wenn wir die Sichtbarkeit ändern wollen, an jeder Stelle, an der das Element verwendet wurde, Änderungen vornehmen müssen, da wir auf öffentliche und private Elemente unterschiedlich zugreifen.
Wir können auch nicht auf private Mitglieder in Methoden zugreifen, die dem Objekt zu einem späteren Zeitpunkt hinzugefügt werden . Dennoch ist das Modul-Muster in vielen Fällen immer noch recht nützlich und hat bei richtiger Anwendung durchaus das Potenzial, die Struktur unserer Anwendung zu verbessern.
Das aufdeckende Modul-Muster
Nachdem wir nun etwas vertrauter mit dem Modulmuster sind, wollen wir uns eine leicht verbesserte Version ansehen - Christian Heilmanns Revealing Module Muster.
Das Revealing Module-Muster entstand, weil Heilmann frustriert war, dass er den Namen des Hauptobjekts wiederholen musste, wenn er eine öffentliche Methode von einer anderen aus aufrufen oder auf öffentliche Variablen zugreifen wollte, und ihm gefiel auch nicht, dass er für die Dinge, die er öffentlich machen wollte, zur Objektliteralschreibweise wechseln musste.
Das Ergebnis seiner Bemühungen war ein aktualisiertes Muster, bei dem wir einfach alle unsere Funktionen und Variablen im privaten Bereich definieren und ein anonymes Objekt mit Zeigern auf die private Funktionalität zurückgeben, die wir als öffentlich offenlegen wollten.
Ein Beispiel für die Verwendung des Revealing Module-Musters finden Sie unten
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
Vorteile
Durch dieses Muster wird die Syntax unserer Skripte einheitlicher. Außerdem wird am Ende des Moduls deutlicher, auf welche unserer Funktionen und Variablen öffentlich zugegriffen werden kann, was die Lesbarkeit erleichtert.
Benachteiligungen
Ein Nachteil dieses Musters ist, dass, wenn eine private Funktion auf eine öffentliche Funktion verweist, diese öffentliche Funktion nicht überschrieben werden kann, wenn ein Patch erforderlich ist. Das liegt daran, dass die private Funktion weiterhin auf die private Implementierung verweist und das Muster nicht für öffentliche Mitglieder, sondern nur für Funktionen gilt.
Für öffentliche Objektmitglieder, die sich auf private Variablen beziehen, gilt ebenfalls die oben erwähnte No-Patch-Regel.
21 Stimmen
Ich kann sehen, wo Sie mit der Überprüfung gehen, um zu sehen, wenn der Namespace genommen wird, aber da das Objekt nicht erstellt werden, wenn dies fehlschlägt, denke ich, der bessere Ansatz ist zu warnen, wenn der Namespace genommen wird. Offen gesagt sollte dies einfach nicht in den meisten JS-Situationen passieren und sollte schnell in der Entwicklung gefangen werden.
19 Stimmen
Nehmen Sie einen "Namespace" der obersten Ebene (Fenstereigenschaft). Besitzen Sie ihn. Konflikte sollten bereits in der Testphase erkannt werden. Machen Sie sich nicht die Mühe, all diese "Was wäre wenn"-Prüfungen hinzuzufügen. Es ist ein fatales Problem für doppelte "Namensräume" und sollte als solches behandelt werden . Sie können einen Ansatz wie jQuery verfolgen, um das Bewohnen eines benutzerdefinierten "Namespace" zu ermöglichen; aber dies ist immer noch eine Frage der Entwurfszeit.
0 Stimmen
Siehe auch stackoverflow.com/questions/2102591/ bei Leistungsproblemen
0 Stimmen
Siehe auch stackoverflow.com/questions/4125479/ für Objekt- und Funktionsnamensräume
0 Stimmen
Dies ist eine Tonne von Informationen, aber wirklich legt die Unterschiede zwischen den verschiedenen JS Design Patterns. Es half mir eine Menge: addyosmani.com/resources/essentialjsdesignpatterns/book
1 Stimmen
Meh, heutzutage haben wir Symbole und Module, so dass doppelte Namespaces nicht einmal ein Problem sein sollten.