サーチ…
オブザーバーパターン
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
メディエーターパターン
メディエーターのパターンを空中の飛行機を制御する飛行制御塔と考えてください。この飛行機は現在着陸しています。待機するのは2番目、離陸するのは3番目の飛行機です。 。
これはメディエーターがどのように機能するか、さまざまなモジュール間の通信ハブとして機能し、モジュールの依存関係を緩和し、結合が緩やかになり、移植性が向上します。
このチャットルームの例では、メディエータのパターンの仕組みについて説明します。
// 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();
}
コマンド
コマンドパターンは、メソッド、現在のオブジェクト状態、および呼び出すメソッドにパラメータをカプセル化します。後でメソッドを呼び出すために必要なすべてをコンパートメント化すると便利です。これは、 "コマンド"を発行し、後でそのコマンドを実行するために使用するコードを決定するために使用することができます。
このパターンには3つの要素があります。
- コマンドメッセージ - メソッド名、パラメータ、状態を含むコマンド自体
- 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では、イテレータはdoneとvalueを返すメソッドとして組み込まれています。イテレータがコレクションの最後にあるときにdoneがtrueになります。
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