Zoeken…


Waarnemer patroon

Het waarnemerspatroon wordt gebruikt voor het afhandelen en delegeren van gebeurtenissen. Een onderwerp onderhoudt een verzameling waarnemers. Het onderwerp waarschuwt deze waarnemers vervolgens wanneer zich een gebeurtenis voordoet. Als je ooit addEventListener hebt gebruikt, heb je het Observer-patroon gebruikt.

function Subject() {
    this.observers = []; // Observers listening to the subject
    
    this.registerObserver = function(observer) {
        // Add an observer if it isn't already being tracked
        if (this.observers.indexOf(observer) === -1) {
            this.observers.push(observer);
        }
    };

    this.unregisterObserver = function(observer) {
        // Removes a previously registered observer
        var index = this.observers.indexOf(observer);
        if (index > -1) {
            this.observers.splice(index, 1);
        }
    };

    this.notifyObservers = function(message) {
        // Send a message to all observers
        this.observers.forEach(function(observer) {
            observer.notify(message);
        });
    };
}

function Observer() {
    this.notify = function(message) {
        // Every observer must implement this function
    };
}

Voorbeeld gebruik:

function Employee(name) {
    this.name = name;

    // Implement `notify` so the subject can pass us messages
    this.notify = function(meetingTime) {
        console.log(this.name + ': There is a meeting at ' + meetingTime);
    };
}

var bob = new Employee('Bob');
var jane = new Employee('Jane');
var meetingAlerts = new Subject();
meetingAlerts.registerObserver(bob);
meetingAlerts.registerObserver(jane);
meetingAlerts.notifyObservers('4pm');

// Output:
// Bob: There is a meeting at 4pm
// Jane: There is a meeting at 4pm

Bemiddelaar patroon

Zie het bemiddelingspatroon als de vluchtcontroletoren die vliegtuigen in de lucht bestuurt: het stuurt dit vliegtuig nu aan land, het tweede om te wachten, en het derde om op te stijgen, enz. Geen vliegtuig mag echter ooit met zijn collega's praten .

Dit is hoe mediator werkt, het werkt als een communicatiehub tussen verschillende modules, op deze manier vermindert u de module-afhankelijkheid van elkaar, verhoogt u de losse koppeling en bijgevolg de draagbaarheid.

Dit Chatroom-voorbeeld legt uit hoe mediatorpatronen werken:

// each participant is just a module that wants to talk to other modules(other participants)
var Participant = function(name) {
    this.name = name;
    this.chatroom = null;
};
 // each participant has method for talking, and also listening to other participants
Participant.prototype = {
    send: function(message, to) {
        this.chatroom.send(message, this, to);
    },
    receive: function(message, from) {
        log.add(from.name + " to " + this.name + ": " + message);
    }
};

 // chatroom is the Mediator: it is the hub where participants send messages to, and receive messages from
var Chatroom = function() {
    var participants = {};
 
    return {
 
        register: function(participant) {
            participants[participant.name] = participant;
            participant.chatroom = this;
        },
 
        send: function(message, from) {
            for (key in participants) {   
                if (participants[key] !== from) {//you cant message yourself !
                    participants[key].receive(message, from);
                }
            }
        }

    };
};
 
// log helper
 
var log = (function() {
    var log = "";
 
    return {
        add: function(msg) { log += msg + "\n"; },
        show: function() { alert(log); log = ""; }
    }
})();
 
function run() {
    var yoko = new Participant("Yoko");
    var john = new Participant("John");
    var paul = new Participant("Paul");
    var ringo = new Participant("Ringo");
 
    var chatroom = new Chatroom();
    chatroom.register(yoko);
    chatroom.register(john);
    chatroom.register(paul);
    chatroom.register(ringo);
 
    yoko.send("All you need is love.");
    yoko.send("I love you John.");        
    paul.send("Ha, I heard that!");
 
    log.show();
}

Commando

Het opdrachtpatroon omvat parameters voor een methode, de huidige objectstatus en welke methode moet worden aangeroepen. Het is handig om alles wat nodig is om een methode op een later tijdstip aan te roepen te compartimenteren. Het kan worden gebruikt om een "commando" te geven en later te beslissen welk stuk code moet worden gebruikt om het commando uit te voeren.

Er zijn drie componenten in dit patroon:

  1. Commando bericht - het commando zelf, inclusief de methode naam, parameters en status
  2. Invoker - het gedeelte dat het commando opdraagt de instructies uit te voeren. Dit kan een getimede gebeurtenis, gebruikersinteractie, een stap in een proces, terugbellen of elke andere manier zijn die nodig is om de opdracht uit te voeren.
  3. Ontvanger - het doelwit van de uitvoering van de opdracht.

Commandobericht als een array

var aCommand = new Array();
aCommand.push(new Instructions().DoThis);  //Method to execute
aCommand.push("String Argument");  //string argument
aCommand.push(777);                //integer argument
aCommand.push(new Object {} );     //object argument
aCommand.push(new Array() );       //array argument

Constructor voor opdrachtklasse

class DoThis {
    constructor( stringArg, numArg, objectArg, arrayArg ) {
        this._stringArg = stringArg;
        this._numArg = numArg;
        this._objectArg = objectArg;
        this._arrayArg = arrayArg;
    }
    Execute() {
       var receiver = new Instructions();
       receiver.DoThis(this._stringArg, this._numArg, this._objectArg, this._arrayArg );
    }
}     

Invoker

aCommand.Execute();  

Kan beroep doen op:

  • direct
  • in reactie op een evenement
  • in een volgorde van uitvoering
  • als een terugbelreactie of als belofte
  • aan het einde van een gebeurtenislus
  • op elke andere manier die nodig is om een methode te gebruiken

Ontvanger

class Instructions {
    DoThis( stringArg, numArg, objectArg, arrayArg ) {
        console.log( `${stringArg}, ${numArg}, ${objectArg}, ${arrayArg}` );
    }
}

Een client genereert een commando, geeft het door aan een invoker die het onmiddellijk uitvoert of het commando vertraagt, en dan werkt het commando op een ontvanger. Het opdrachtpatroon is erg handig in combinatie met begeleidende patronen om berichtpatronen te maken.

iterator

Een iteratorpatroon biedt een eenvoudige methode om achtereenvolgens het volgende item in een verzameling te selecteren.


Vaste verzameling

class BeverageForPizza {
    constructor(preferenceRank) {
        this.beverageList = beverageList;
        this.pointer = 0;
    }
    next() {
        return this.beverageList[this.pointer++];
    }

var withPepperoni = new BeverageForPizza(["Cola", "Water", "Beer"]);
withPepperoni.next(); //Cola
withPepperoni.next(); //Water
withPepperoni.next(); //Beer

In ECMAScript 2015 zijn iterators ingebouwd als een methode die klaar en waardevol is. klaar is waar wanneer de iterator aan het einde van de verzameling is

function preferredBeverage(beverage){
    if( beverage == "Beer" ){
        return true;
    } else {
        return false;
    }
}
var withPepperoni = new BeverageForPizza(["Cola", "Water", "Beer", "Orange Juice"]);
for( var bevToOrder of withPepperoni ){
    if( preferredBeverage( bevToOrder ) {
        bevToOrder.done; //false, because "Beer" isn't the final collection item
        return bevToOrder; //"Beer"
    }
}

Als een generator

class FibonacciIterator {
    constructor() {
        this.previous = 1;
        this.beforePrevious = 1;
    }
    next() {
        var current = this.previous + this.beforePrevious;
        this.beforePrevious = this.previous;
        this.previous = current;
        return current;
    }
}

var fib = new FibonacciIterator();
fib.next(); //2
fib.next(); //3
fib.next(); //5

In ECMAScript 2015

function* FibonacciGenerator() {  //asterisk informs javascript of generator 
    var previous = 1;
    var beforePrevious = 1;
    while(true) {
        var current = previous + beforePrevious;
        beforePrevious = previous;
        previous = current;
        yield current;  //This is like return but 
                        //keeps the current state of the function
                        // i.e it remembers its place between calls
    }
}

var fib = FibonacciGenerator();
fib.next().value; //2
fib.next().value; //3
fib.next().value; //5
fib.next().done; //false


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow