Peter Seibel, Autor von Practical Common Lisp, sagte einmal, wenn Sie ein Muster benötigen, muss etwas falsch sein. Das Problem, das er erwähnte, bezieht sich auf die Notwendigkeit, aufgrund der inhärenten Sprachfehler eine allgemeine Lösung zu suchen und zusammenzufassen.
Egal, ob es sich um einen schwachen oder starken Typ, eine statische oder dynamische Sprache, eine imperative oder beschreibende Sprache handelt, jede Sprache hat ihre eigenen Vor- und Nachteile. Ein jamaikanischer Athlet hat einige Vorteile beim Sprinten und sogar beim Boxen, aber es fehlt einige im praktizierenden Yoga.
Hexenmeister und Schattenpriester können leicht ein ausgezeichnetes Auxiliar sein, während eine feindliche Magie, die mit Macon auf seinem Rücken herumfliegt, etwas umständlich wäre. Um zum Programm zu wechseln, kann es viel Anstrengungen erfordern, um den Dekorateur in der statischen Sprache zu implementieren. Da JS jederzeit Methoden auf Objekte werfen kann, wird das Dekorationsmuster in JS nutzlos.
Es gibt einige Bücher über JavaScript -Designmuster. "Pro JavaScript -Designmuster" ist ein klassisches Buch, aber die Beispiele darin sind ziemlich ausführlich. Basierend auf dem Code, den ich bei der Arbeit geschrieben habe, werde ich mein Verständnis zusammenfassen. Wenn mein Verständnis voreingenommen ist, stellen Sie bitte sicher, dass Sie es korrigieren.
1. Singleton -Modus
Die Definition eines Singleton -Musters besteht darin, eine einzigartige Instanz einer Klasse zu erstellen, aber JS selbst ist eine "klassenlose" Sprache. Viele Artikel, die über JS -Designmuster sprechen, verwenden {} als Singleton und machen Sinn. Da es viele Möglichkeiten gibt, Objekte durch JS zu generieren, schauen wir uns einen anderen sinnvolleren Singleton an.
Es ist häufig erforderlich, dass beim Klicken auf eine Schaltfläche eine Maskenebene auf der Seite auftauchen muss. Wenn Sie beispielsweise auf Web.qq.com klicken, um sich anzumelden.
Dieser Code, der eine graue Hintergrundmaskenebene generiert, ist leicht zu schreiben.
Die Codekopie lautet wie folgt:
var CreateMask = function () {
Rückgabedokument, Body.AppendChild (document.createelement (div));
}
$ ('Schaltfläche') .click (function () {
Var mask = CreateMask ();
mask.show ();
})
Das Problem ist, dass diese Maskenebene global einzigartig ist. Jedes Mal, wenn Sie CreateMask aufrufen, wird ein neues DIV erstellt, obwohl sie entfernt werden kann, während Sie die Maskenschicht verstecken. Es ist jedoch offensichtlich unangemessen, dies zu tun.
Schauen wir uns die zweite Lösung an und erstellen Sie diese DIV zu Beginn der Seite. Beachten Sie es dann mit einer Variablen.
Die Codekopie lautet wie folgt:
var mask = document.body.Appendchild (document.createelement ("div '));
$ ("Button ') .click (function () {
mask.show ();
})
Dies bedeutet nicht, dass auf der Seite nur eine Maskenschicht -Div erstellt wird, sondern ein weiteres Problem folgt. Vielleicht brauchen wir diese Maskenschicht nie, die eine DIV verschwendet, und Sie sollten sehr geizig über jede Operation des DOM -Knotens sein.
Wenn Sie eine Variable verwenden können, stellen Sie fest, ob eine DIV erstellt wurde?
Die Codekopie lautet wie folgt:
var Maske;
var CreateMask = function () {
if (Maske) Rückmaske;
anders{
mask = document, body.Appendchild (document.createelement (div));
Rückmaske;
}
}
Es sieht gut aus, aber hier habe ich eine Funktion ausgeschlossen, die ein einzelnes Spaltenobjekt generiert. Schauen wir uns genauer an, was mit diesem Code falsch ist.
Zunächst hat diese Funktion bestimmte Nebenwirkungen. Die Funktion ändert die Referenz auf die externe Variablenmaske im Funktionskörper. In einem Multi-Personen-Kollaborationsprojekt ist CreateMask eine unsichere Funktion. Andererseits ist die globale variable Maske keine notwendige. Lassen Sie es uns verbessern.
Die Codekopie lautet wie folgt:
var CreateMask = function () {
var Maske;
return function () {
Rückmaske || (mask = document.body.Appendchild (document.createelement ('div')))
}
} ())
Ein einfacher Verschluss wird verwendet, um die variable Maske zu wickeln, zumindest für die CreateMask -Funktion, sie ist geschlossen.
Vielleicht ist das Singleton -Muster, wenn ich das sehe, zu einfach. In der Tat sind einige Designmuster sehr einfach. Auch wenn ich nie auf das Konzept der Designmuster geachtet habe, habe ich einige Designmuster in meinem täglichen Code verwendet, ohne es zu wissen. Genau wie ich verstanden habe, was der Wagen eines alten Mannes ist, habe ich vor vielen Jahren darüber nachgedacht, dass dies der Karren eines alten Mannes ist.
Die 23 Entwurfsmuster in GOF sind auch Muster, die in der Softwareentwicklung wiederholt existiert und wiederholt verwendet wurden. Wenn der Programmierer nicht klar ist, dass er bestimmte Muster verwendet hat, kann er das nächste Mal ein geeigneteres Design verpassen (diese Passage stammt aus der "Welt der Programmierung in Matsumoto".
Kehren wir zum Thema zurück, der vorherige Singleton hat immer noch seine Nachteile. Es kann nur zum Erstellen von Maskenschichten verwendet werden. Was ist, wenn ich eine Funktion schreiben muss, um ein eindeutiges XHR -Objekt zu erstellen? Kann ich einen allgemeinen Singleton -Wrapper finden?
Funktionen in JS sind der erste Typ, was bedeutet, dass Funktionen auch als Parameter übergeben werden können. Schauen wir uns den endgültigen Code an.
Die Codekopie lautet wie folgt:
var Singleton = Funktion (fn) {
var Ergebnis;
return function () {
Rückgabeergebnis || (Ergebnis = fn .Apply (this, Argumente));
}
}
var CreateMask = Singleton (function () {
return document.body.appendchild (document.createelement ('div'));
})
Verwenden Sie eine Variable, um den ersten Rückgabewert zu speichern. Wenn es zugewiesen wurde, wird die Variable in nachfolgenden Anrufen zuerst zurückgegeben. Der Code, der die Maskenebene wirklich erstellt hat, wird über die Rückruffunktion an den Singleton -Wrapper übergeben. Diese Methode wird tatsächlich als Brückenmodus bezeichnet. In Bezug auf den Brückenmodus wird es etwas später eingestellt.
Die Singleton -Funktion ist jedoch nicht perfekt, es erfordert immer ein variables Ergebnis, um den Verweis auf die DIV zu registrieren. Leider reichen die funktionalen Eigenschaften von JS nicht aus, um Deklarationen und Aussagen vollständig zu beseitigen.