Suche…
Beobachtermuster
Das Observer- Muster wird für die Ereignisbehandlung und Delegierung verwendet. Ein Thema unterhält eine Sammlung von Beobachtern. Das Subjekt benachrichtigt diese Beobachter dann, wenn ein Ereignis auftritt. Wenn Sie addEventListener
jemals verwendet haben, addEventListener
Sie das Observer-Muster verwendet.
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
};
}
Verwendungsbeispiel:
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
Vermittler-Muster
Stellen Sie sich das Vermittlermuster als den Flugkontrollturm vor, der Flugzeuge in der Luft kontrolliert: Er weist dieses Flugzeug an, jetzt zu landen, das zweite zu warten und das dritte zu starten, usw. Jedoch darf kein Flugzeug mit seinen Kollegen sprechen .
So funktioniert Mediator, er fungiert als Kommunikationsknoten zwischen verschiedenen Modulen. Auf diese Weise reduzieren Sie die Modulabhängigkeit voneinander, erhöhen die lose Kopplung und folglich die Portabilität.
Dieses Chatroom-Beispiel erläutert, wie Vermittlermuster funktionieren:
// 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();
}
Befehl
Das Befehlsmuster kapselt Parameter in eine Methode, den aktuellen Objektstatus und die aufzurufende Methode. Es ist nützlich, alles zu unterteilen, um eine Methode zu einem späteren Zeitpunkt aufzurufen. Es kann verwendet werden, um einen "Befehl" auszugeben und später zu entscheiden, welcher Code zum Ausführen des Befehls verwendet werden soll.
Es gibt drei Komponenten in diesem Muster:
- Befehlsnachricht - Der Befehl selbst, einschließlich Methodenname, Parameter und Status
- Invoker - der Teil, der den Befehl anweist, seine Anweisungen auszuführen. Dies kann ein zeitgesteuertes Ereignis, Benutzerinteraktion, ein Schritt in einem Prozess, ein Rückruf oder ein beliebiger Weg sein, um den Befehl auszuführen.
- Empfänger - das Ziel der Befehlsausführung.
Befehlsnachricht als 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
Konstruktor für die Befehlsklasse
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 );
}
}
Einladen
aCommand.Execute();
Kann aufrufen:
- sofort
- als Reaktion auf eine Veranstaltung
- in einer Reihenfolge der Ausführung
- als Rückruf oder in einem Versprechen
- am Ende einer Ereignisschleife
- auf andere Weise zum Aufrufen einer Methode
Empfänger
class Instructions {
DoThis( stringArg, numArg, objectArg, arrayArg ) {
console.log( `${stringArg}, ${numArg}, ${objectArg}, ${arrayArg}` );
}
}
Ein Client generiert einen Befehl, übergibt ihn an einen Aufrufer, der ihn entweder sofort ausführt oder den Befehl verzögert, und der Befehl wirkt dann auf einen Empfänger. Das Befehlsmuster ist sehr nützlich, wenn es zusammen mit Begleitmustern zum Erstellen von Nachrichtenmustern verwendet wird.
Iterator
Ein Iterator-Muster bietet eine einfache Methode zum sequentiellen Auswählen des nächsten Elements in einer Sammlung.
Feste Sammlung
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 sind Iteratoren eine integrierte Methode, die erledigte Werte und Werte zurückgibt. done ist wahr, wenn sich der Iterator am Ende der Sammlung befindet
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 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