Поиск…
Схема наблюдателя
Шаблон Observer используется для обработки событий и делегирования. Предмет поддерживает коллекцию наблюдателей. Затем субъект уведомляет об этом наблюдателей всякий раз, когда происходит событие. Если вы когда-либо использовали addEventListener
вы использовали шаблон 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
};
}
Пример использования:
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
Посредник
Подумайте о шаблоне посредника как о башне управления полетом, которая управляет самолетами в воздухе: он направляет этот самолет на посадку сейчас, второй - на ожидание, а третий - на вылет и т. Д. Однако никому не разрешается разговаривать со своими сверстниками ,
Именно так работает медиатор, он работает как концентратор связи между различными модулями, таким образом вы уменьшаете зависимость модуля друг от друга, увеличиваете свободную связь и, следовательно, мобильность.
В этом примере чата объясняется, как работают шаблоны посредников:
// 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();
}
команда
Шаблон команды инкапсулирует параметры в метод, текущее состояние объекта и какой метод вызывать. Полезно разделить все, что необходимо для вызова метода в более позднее время. Его можно использовать для выдачи «команды» и позже решить, какой фрагмент кода использовать для выполнения команды.
В этом шаблоне есть три компонента:
- Командное сообщение - сама команда, включая имя метода, параметры и состояние
- Invoker - часть, которая инструктирует команду выполнить свои инструкции. Это может быть событие времени, взаимодействие с пользователем, шаг в процессе, обратный вызов или любой способ, необходимый для выполнения команды.
- Reciever - цель выполнения команды.
Командное сообщение как массив
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
Конструктор для командного класса
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 );
}
}
Чешуи
aCommand.Execute();
Может ссылаться:
- немедленно
- в ответ на событие
- в последовательности выполнения
- как ответ обратного вызова или обещание
- в конце цикла события
- любым другим способом для вызова метода
Получатель
class Instructions {
DoThis( stringArg, numArg, objectArg, arrayArg ) {
console.log( `${stringArg}, ${numArg}, ${objectArg}, ${arrayArg}` );
}
}
Клиент генерирует команду, передает ее вызову, который либо выполняет его немедленно, либо задерживает команду, а затем команда действует на приемник. Шаблон команды очень полезен, когда используется сопутствующими шаблонами для создания шаблонов сообщений.
Итератор
Шаблон итератора предоставляет простой метод для выбора, последовательно следующего элемента в коллекции.
Фиксированная коллекция
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
В ECMAScript 2015 итераторы являются встроенными в качестве метода, который возвращает результат и значение. сделано верно, когда итератор находится в конце коллекции
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"
}
}
Как генератор
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
В 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