JavaScript-Entwurfsmuster – Muster der Verantwortungskette

JavaScript-Entwurfsmuster – Muster der Verantwortungskette

Überblick

Das Verantwortungskettenmuster ist ein verhaltensbezogenes Entwurfsmuster im Entwurfsmuster.

Definition: Geben Sie mehreren Objekten die Möglichkeit, eine Anforderung zu verarbeiten. Vermeiden Sie dadurch die Kopplungsbeziehung zwischen dem Absender und dem Empfänger der Anforderung. Bilden Sie eine Kette von Objekten, die die Anforderung verarbeiten, und leiten Sie die Anforderung entlang der Kette weiter, bis ein Objekt sie verarbeitet.

Erklärung in einfacher Sprache: Der Autor lebt in Wuhan, einer neuen Stadt der ersten Kategorie mit über 10 Millionen Einwohnern. Nehmen wir als Beispiel den Bus zur morgendlichen Hauptverkehrszeit: Die Vordertür des Busses ist während der morgendlichen Hauptverkehrszeit normalerweise verstopft, sodass es unmöglich ist, die Karte durchzuziehen, um in den Bus einzusteigen; aber die Hintertür ist relativ leer. Zu diesem Zeitpunkt entscheiden wir uns, durch die Hintertür in den Bus einzusteigen, aber wir können die Karte nicht durchziehen, wenn wir durch die Hintertür in den Bus einsteigen; vor der Rechnung davonlaufen? Nein, das ist nicht das, was wir als zivilisierte und gut ausgebildete junge Leute der neuen Generation tun sollten. Also reichen wir die Buskarte nach vorne und bitten den Passagier vor uns, uns dabei zu helfen, sie zum Kartenleser zu reichen, um die Karte durchzuziehen. Wir sind jedoch an der Hintertür und der Kartenleser ist an der Vordertür. Während wir die Karte reichen, bitten wir mehrere Passagiere, uns dabei zu helfen, die Buskarte zu reichen. Dieser Vorgang des Reichens ist ein Verantwortungskettenmodell, und jeder Passagier, der die Karte reicht, ist ein Knotenobjekt in der Verantwortungskette.

Code-Implementierung

Angenommen, es gibt eine E-Commerce-Website, die Mobiltelefone verkauft. Nach zwei Reservierungsrunden mit einer Anzahlung von 500 Yuan bzw. einem Listenpreis von 200 Yuan (die Bestellung wird zu diesem Zeitpunkt generiert) hat sie nun die Phase des formellen Kaufs erreicht. Für Kunden, die eine Anzahlung geleistet haben, gelten für das Unternehmen bestimmte Vorzugskonditionen. Bei einem formellen Kauf erhalten Kunden, die eine Anzahlung von 500 Yuan geleistet haben, einen Mall-Coupon im Wert von 100 Yuan, und Kunden, die 200 Yuan bezahlt haben, erhalten einen Mall-Coupon im Wert von 50 Yuan. Kunden, die zuvor keine Anzahlung geleistet haben, haben keine Coupons und können das Produkt möglicherweise nicht kaufen, wenn der Vorrat begrenzt ist.

Parameterdefinition

1.orderType: Gibt den Auftragstyp an (Einzahlungsbenutzer oder normaler Benutzer). Wenn der Codewert 1 ist, bedeutet dies, dass der Benutzer eine Einzahlung von 500 Yuan hat, wenn er 2 ist, bedeutet dies, dass der Benutzer eine Einzahlung von 200 Yuan hat, und wenn er 3 ist, bedeutet dies, dass der Benutzer eine Einzahlung von 300 Yuan hat.

2.pay: Gibt an, ob der Benutzer die Anzahlung geleistet hat, der Wert ist true oder false. Obwohl der Benutzer eine Bestellung mit einer Anzahlung von 500 Yuan aufgegeben hat, kann er, wenn er die Anzahlung nicht bezahlt hat, nur als normaler Benutzer einkaufen.

3. Lagerbestand: Gibt die Lagermenge an, die normale Benutzer zum Kauf von Mobiltelefonen benötigen. Kunden, die eine Anzahlung von 500 Yuan oder 200 Yuan geleistet haben, unterliegen nicht dieser Einschränkung.

erreichen

var order = function(Bestelltyp, Bezahlung, Lagerbestand){
    if ( orderType === 1 ){ // 500 Yuan Anzahlung Kaufmodusif ( pay === true ){ // Anzahlung bezahltconsole.log( '500 Yuan Anzahlung vorbestellen, 100 Gutscheine bekommen' );
        }else{ // Anzahlung nicht bezahlt, Downgrade auf normalen Kaufmodusif ( stock > 0 ){ // Mobiltelefone für normalen Kauf sind noch auf Lagerconsole.log( 'Normaler Kauf, kein Coupon' );

            }anders{
                console.log('Unzureichender Mobiltelefonbestand');
            }
        }
    }
    sonst wenn (Bestelltyp === 2) { // 200 Yuan Anzahlung Kaufmodus wenn (Zahlung === wahr) {
            console.log('Bestellen Sie mit 200 Yuan Anzahlung vor und erhalten Sie einen 50-Yuan-Gutschein');
        }anders{
            wenn (Aktie > 0) {
                console.log('Normaler Kauf, kein Coupon');
            }anders{
                console.log('Unzureichender Mobiltelefonbestand');
            }
        }
    }
    sonst wenn ( Bestelltyp === 3 ) {
        wenn (Aktie > 0) {
            console.log('Normaler Kauf, kein Coupon');
        }anders{
            console.log('Unzureichender Mobiltelefonbestand');
        }
    }
};
order( 1 , true, 500); // 500 Yuan Anzahlung bei Vorbestellung, 100 Yuan Gutschein erhalten

Der obige Code kann sicherlich die erforderlichen Funktionen erreichen, aber die Struktur des obigen Codes ist offensichtlich unklar und die Reihenfolge der Funktionsmethode ist riesig und weist einen hohen Grad an Kopplung auf.

Implementierung des Verantwortungskette-Musters

Wir verwenden das Verantwortungskettenmuster, um die oben genannten Funktionen zu implementieren. Wir teilen zunächst die 500-Yuan-Einzahlungsbestellung, die 200-Yuan-Einzahlungsbestellung und die normale Bestellung in drei Funktionen auf und übergeben dann die drei Parameter Bestelltyp, Bezahlung und Bestand. Wenn die 500-Yuan-Bestellfunktion die Verarbeitungsbedingungen nicht erfüllt, wird die Anforderung an die 200-Yuan-Bestellfunktion übergeben. Wenn die 200-Yuan-Bestellfunktion die Verarbeitungsbedingungen ebenfalls nicht erfüllt, wird die Anforderung an die normale Bestellfunktion übergeben.

var order500 = function(Bestelltyp, Bezahlung, Lagerbestand) {
    wenn ( Bestelltyp === 1 und Bezahlung === wahr ){
        console.log('Bestellen Sie mit einer Anzahlung von 500 Yuan vor und erhalten Sie einen Gutschein über 100 Yuan');
    }anders{
        order200( orderType, pay, stock ); // Übergebe die Anfrage an die 200 Yuan Bestellung }
};
// 200 Yuan Bestellung var order200 = function(Bestelltyp, Bezahlung, Lagerbestand){
    wenn ( Bestelltyp === 2 und Bezahlung === wahr ){
        console.log('Bestellen Sie mit 200 Yuan Anzahlung vor und erhalten Sie einen 50-Yuan-Gutschein');
    }anders{
        orderNormal( orderType, pay, stock ); // Übergebe die Anfrage an eine normale Bestellung }
};
// Normale Kauforder var orderNormal = function( orderType, pay, stock ){
    wenn (Aktie > 0) {
        console.log('Normaler Kauf, kein Coupon');
    }anders{
        console.log('Unzureichender Mobiltelefonbestand');
    }
};

// Testergebnisse:
order500( 1 , true, 500 ); // 500 Yuan Anzahlung für Vorbestellung, bekomme 100 Yuan Couponorder500( 1, false, 500 ); // Normaler Kauf, kein Couponorder500( 2, true, 500 ); // 200 Yuan Anzahlung für Vorbestellung, bekomme 500 Yuan Couponorder500( 3, false, 500 ); // Normaler Kauf, kein Couponorder500( 3, false, 0 ); // Ausverkauft

Sie können sehen, dass die Struktur des geänderten Codes viel klarer ist als zuvor, die Funktionen sind aufgeteilt und viele if-else-Verzweigungsurteile wurden entfernt;

Selbst wenn dies der Fall ist, verstößt der geänderte Code immer noch gegen das Open/Closed-Prinzip, denn wenn sich unsere Anforderungen später ändern, müssen wir die Interna dieser Funktionen ändern; das ist offensichtlich nicht das, was wir wollen.

Verbesserung

Wir vereinbaren zunächst, dass die Funktion „nextSuccessor“ zurückgibt, wenn sie die Verarbeitungsbedingungen nicht erfüllt, und dass sie ausgeführt wird, wenn sie die Verarbeitungsbedingungen erfüllt.

var order500 = function(Bestelltyp, Bezahlung, Lagerbestand) {
    wenn ( Bestelltyp === 1 und Bezahlung === wahr ){
        console.log('Bestellen Sie mit einer Anzahlung von 500 Yuan vor und erhalten Sie einen Gutschein im Wert von 100 Yuan');
    }anders{
        return 'nextSuccessor'; // Ich weiß nicht, wer der nächste Knoten ist, also leite ich die Anfrage trotzdem nach hinten weiter}
};

var order200 = function(Bestelltyp, Bezahlung, Lagerbestand) {
    wenn ( Bestelltyp === 2 und Bezahlung === wahr ){
        console.log('Bestellen Sie mit einer Anzahlung von 200 Yuan vor und erhalten Sie einen Gutschein im Wert von 50 Yuan');
    }anders{
        return 'nextSuccessor'; // Ich weiß nicht, wer der nächste Knoten ist, also leite ich die Anfrage trotzdem nach hinten weiter}
};

var orderNormal = function(Bestelltyp, Bezahlung, Lagerbestand) {
    wenn (Aktie > 0) {
        console.log('Normaler Kauf, kein Coupon');
    }anders{
        console.log('Unzureichender Mobiltelefonbestand');
    }
};

var Kette = Funktion( fn ){
    dies.fn = fn;
    dieser.Nachfolger = null;
};

//Die Anfrage an den nächsten Knoten weiterleiten Chain.prototype.setNextSuccessor = function( successor ){
    returniere this.successor = Nachfolger;
};

//Übergeben Sie die Anfrage an einen Knoten Chain.prototype.passRequest = function(){

   //Die Methode nach dem Empfangen der Instanz und Speichern der Parameter als Array var ret = this.fn.apply( this, arguments );
    Konsole.log(ret);

    //ret ist gleich nextSuccessor, was bedeutet, dass die Verarbeitungsbedingungen nicht erfüllt sind und die Ausführung fortgesetzt werden muss, wenn (ret === 'nextSuccessor') {

     //Dies ist eine logische Kurzschlussrückgabe. Wenn eine der Vereinigungen falsch ist, ist sie falsch. Wenn this.successor vorhanden ist, wird das nachfolgende Ausführungsergebnis zurückgegeben. Wenn this.successor nicht vorhanden ist, wird der Wert von this.nextSuccessor zurückgegeben, der undefiniert ist.
        gib diesen.Nachfolger zurück und diesen.Nachfolger.passRequest.apply( diesen.Nachfolger, Argumente );
    }
};


var chainOrder500 = neue Kette (order500);
var chainOrder200 = neue Kette( order200 );
var chainOrderNormal = neue Kette( orderNormal );    

//Weitergabe an die Kette der Verantwortungsknoten chainOrder500.setNextSuccessor( chainOrder200 );
chainOrder200.setNextSuccessor( chainOrderNormal );

chainOrder500.passRequest( 1, true, 500 ); // 500 Yuan Anzahlung bei Vorbestellung, erhalte 100 Gutscheine chainOrder500.passRequest( 2, true, 500 ); // 200 Yuan Anzahlung bei Vorbestellung, erhalte 50 Gutscheine chainOrder500.passRequest( 3, true, 500 ); // Normaler Kauf, keine Gutscheine chainOrder500.passRequest( 1, false, 0 ); // Ausverkauft

Selbst wenn sich die Nachfrage nach der Verbesserung ändert und eine Bestellung mit einer Anzahlung von 300 erforderlich ist, können wir dies problemlos bewältigen.

var order300=function(){
  //Spezifisches Implementierungsverhalten};

chainOrder300=neueKette(order300);
chainOrder500.setNextSuccessor(chainOrder300);
chainOrder300.setNextSuccessor(chainOrder200);

Tipps:

Ergänzendes Wissen: logischer Kurzschluss; obwohl dies die Grundkenntnisse von JS sind, ist es unvermeidlich, sie zu vergessen. Ich habe sie vergessen, als ich diesen Artikel schrieb;

Wenn eine der Vereinigungen falsch ist, ist das Ergebnis falsch : Wenn es sich um eine Vereinigungs- (und-)Beziehung handelt, ist die erste Zahl falsch oder existiert nicht, und der Wert der zweiten Zahl wird direkt zurückgegeben;

var x = a && b && c ist gleichbedeutend mit var x = a;
wenn(a){
    x = b;
    wenn(b){
       x = c;
    }
}

Wenn eine der beiden Zahlen wahr ist, dann gilt : Handelt es sich um eine Oder-Menge-Beziehung (oder), dann wird, wenn die erste Zahl wahr ist, direkt die erste Zahl zurückgegeben; ist die erste Zahl falsch, dann wird direkt die zweite Zahl zurückgegeben;

var x = a || b || c ist gleichbedeutend mit:

var x;
wenn(a){
    x = ein;
} sonst wenn(b){
    x = b;
} anders {
    x = c;
}

Denken Sie an die beiden fettgedruckten Sätze oben, und Sie können logische Kurzschlüsse grundsätzlich geschickt einsetzen.

Oben sind die Details des Verantwortungskettenmusters des JavaScript-Entwurfsmusters aufgeführt. Weitere Informationen zum JavaScript-Entwurfsmuster finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • JavaScript-Entwurfsmuster, Lernadaptermuster
  • JavaScript-Entwurfsmuster, Proxy-Muster lernen
  • JavaScript-Entwurfsmuster, Befehlsmuster
  • Detaillierte Erläuterung mehrerer gängiger Entwurfsmuster in js
  • JavaScript-Entwurfsmuster-Strategie, Musterimplementierungsprinzip, detaillierte Erklärung
  • JavaScript-Kombinationsdesignmuster - Einführung in die Verbesserung - Fallanalyse
  • JavaScript-Entwurfsmuster – Analyse der Einführung von Bridge-Muster-Operationsbeispielen
  • JavaScript-Entwurfsmuster – Beispielanalyse für einfache Factory-Muster [XHR Factory Case]
  • JavaScript-Entwurfsmuster – Detaillierte Definition und Anwendungsfälle des Simple Factory Pattern
  • JAVAs sechs Prinzipien der Entwurfsmuster

<<:  VPS erstellt Offline-Download-Server (nach der Ära der Netzwerkfestplatten)

>>:  Bei der Verwendung von MySQL aufgetretene Probleme

Artikel empfehlen

MySQL Serie 13 MySQL-Replikation

Inhaltsverzeichnis 1. Mit der MySQL-Replikation v...

So erstellen Sie YUM in einer Centos7-Umgebung

1. Geben Sie die Konfigurationsdatei der Yum-Quel...

CSS-Isolationsproblem in Blazor

1. Umwelt VS 2019 16.9.0 Vorschau 1.0 .NET SDK 5....

Wie überwacht und erhält Zabbix Netzwerkgerätedaten über SSH?

Szenariosimulation: Das Betriebs- und Wartungsper...

Detaillierte Erklärung der JSONObject-Verwendung

JSONObject ist lediglich eine Datenstruktur, die ...

Verwendung des Linux-Befehls xargs

1. Funktion: xargs kann die durch Leerzeichen ode...

Zwei Möglichkeiten zum Deklarieren privater Variablen in JavaScript

Vorwort JavaScript unterscheidet sich von anderen...

Unterschied zwischen HTML ReadOnly und Enabled

Das Textfeld mit dem ReadOnly-Attribut wird auf de...

CentOS 8 offiziell veröffentlicht, basierend auf Red Hat Enterprise Linux 8

Das CentOS-Projekt, ein 100 % kompatibler Neuaufb...

So implementieren Sie Parallelitätskontrolle in JavaScript

Inhaltsverzeichnis 1. Einführung in die Paralleli...