Recherche…
Motif d'observateur
Le modèle Observer est utilisé pour la gestion des événements et la délégation. Un sujet maintient une collection d' observateurs. Le sujet informe alors ces observateurs chaque fois qu'un événement se produit. Si vous avez déjà utilisé addEventListener
vous avez utilisé le modèle Observer.
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
};
}
Exemple d'utilisation:
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
Modèle de médiateur
Considérez le modèle de médiateur comme la tour de contrôle de vol qui contrôle les avions en vol: il ordonne à l’avion de atterrir maintenant, le deuxième à attendre et le troisième à décoller, etc. .
C'est ainsi que fonctionne le médiateur, qui fonctionne comme un concentrateur de communication entre différents modules. Vous réduisez ainsi la dépendance des modules, augmentez le couplage et par conséquent la portabilité.
Cet exemple de Chatroom explique le fonctionnement des patrons de médiateur:
// 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();
}
Commander
Le modèle de commande encapsule les paramètres dans une méthode, l'état actuel de l'objet et la méthode à appeler. Il est utile de compartimenter tout ce qui est nécessaire pour appeler une méthode ultérieurement. Il peut être utilisé pour émettre une "commande" et décider plus tard quel morceau de code utiliser pour exécuter la commande.
Il y a trois composants dans ce modèle:
- Message de commande - la commande elle-même, y compris le nom de la méthode, les paramètres et l'état
- Invoker - la partie qui demande à la commande d'exécuter ses instructions. Il peut s'agir d'un événement chronométré, d'une interaction utilisateur, d'une étape d'un processus, d'un rappel ou de tout autre moyen nécessaire pour exécuter la commande.
- Reciever - la cible de l'exécution de la commande.
Message de commande en tant que tableau
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
Constructeur pour la classe de commande
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 );
}
}
Invocateur
aCommand.Execute();
Peut invoquer:
- immédiatement
- en réponse à un événement
- dans une séquence d'exécution
- comme une réponse de rappel ou dans une promesse
- à la fin d'une boucle d'événement
- de toute autre manière nécessaire pour invoquer une méthode
Destinataire
class Instructions {
DoThis( stringArg, numArg, objectArg, arrayArg ) {
console.log( `${stringArg}, ${numArg}, ${objectArg}, ${arrayArg}` );
}
}
Un client génère une commande, la transmet à un invocateur qui l'exécute immédiatement ou retarde la commande, puis la commande agit sur un récepteur. Le modèle de commande est très utile lorsqu'il est utilisé avec des modèles compagnons pour créer des modèles de messagerie.
Itérateur
Un modèle d'itérateur fournit une méthode simple pour sélectionner, de manière séquentielle, l'élément suivant dans une collection.
Collection fixe
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
Dans ECMAScript 2015, les itérateurs sont une méthode intégrée qui renvoie les données et les valeurs. done est vrai lorsque l'itérateur est à la fin de la collection
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"
}
}
En tant que générateur
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
Dans 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