blog

ObserverパターンとPublish-Subscriberパターンを少し試してみる

Observe パターンでは、ルーラを受け取りたいオブザーバは、内容が変更されたイベントを購読する必要があります。 このパターンはサブスクライバとパブリッシャの間に位置するトピック/イベントチャネルを...

May 26, 2020 · 4 min. read
シェア

/*

Observeパターンでは、ルーラーを受け取りたいオブザーバーは、内容が変更されたイベントを購読する必要があります。Subscribe/Publish パターンは、サブスクライバとパブリッシャの間に位置するトピック/イベントチャネルを使用します。このイベントシステムによって、サブスクライバーが必要とする値を含むカスタムパラメータを渡すことができる、アプリケーション固有のイベントをコードで定義することができます。目標は、サブスクライバーとパブリッシャーが依存しないようにすることです。

オブザーバーパターンとの違いは、サブスクライバーが適切なイベントハンドラを実行することで、パブリッシャーからの通知を登録し受け取ることができるという点です。

オブザーバパターンのターゲットオブジェクトはオブザーバを維持する責任があります。パブリッシュ/サブスクライブパターンのパブリッシャーは、サブスクライバーのことは気にしません。オブザーバーパターンでは、オブザーバーはインターフェースを提供する必要があります。そして、ターゲットオブジェクトが変更されると、このインターフェースが呼び出され、ターゲットの状態と一致するようにします。つまり、全てのオブザーバーは統一されたインターフェイスを必要とします。 パブリッシュ/サブスクライブモデルでは、サブスクライバーイベントはそのようなインターフェイスによってトリガーされるのではなく、サブスクライバーがリスニングしている特定のメッセージによってトリガーされます。 サブスクライバーはパブリッシャーをリスニングしているのではなく、メッセージのプールをリスニングしていると理解することができます。サブスクライバーはパブリッシャーではなく、メッセージプールをリスニングしていると理解できます。このメッセージを誰が発行したかは関係ありません。

class Observe{
 constructor() {
 this.handlers = {};
 }
 // 登録イベントをバインドする
 register(type, hander) {
 // 登録されたイベントタイプが以前に登録されていない場合、登録は直接行われる
 if (!this.handlers.hasOwnProperty(type)) {
 this.handlers[type] = []
 } 
 
 this.handlers[type].push(hander)
 
 return this
 }
 // イベントをトリガーする
 emit(...args) {
 let type = Array.prototype.shift.call(args)
 if (this.handlers.hasOwnProperty(type)) {
 // console.log(this.handlers[type])
 this.handlers[type].forEach(item => {
 // console.log(item)
 item.apply(item, args)
 });
 } else {
 throw new Error(`${type} event isn't register`)
 }
 return this
 }
}
let observe = new Observe();
observe.register('hello', function(a) {
 console.log(a)
})
observe.emit('hello',[1,2,4])
observe.emit('word',2)

// オブザーバーパターン

function ObserveList() {
 this.observeList = [];
}

// オブザーバーにメソッドを追加

ObserveList.prototype.add = function (obj) { 
 return this.observeList.push(obj);
}

// のオブザーバーの数を数えます。

ObserveList.prototype.count = function () { 
 return this.observeList.length;
}

// 現在のオブザーバー内の特定のオブザーバーを取得します。

ObserveList.prototype.get = function (index) { 
 if (index > -1 && index < this.observeList.length) {
 return this.observeList[index]
 }
}

// オブザーバ内のインデックスを取得

ObserveList.prototype.indexOf = function (obj, startIndex) { 
 let i = startIndex || 0;
 while(i < this.observeList.length) {
 if (this.observeList[i] === obj) {
 return i
 }
 i++
 }
 return -1
}

// 現在のオブザーバーを削除

ObserveList.prototype.removeAt = function (index) { 
 this.observeList.splice(index, 1);
}

// // オブザーバーのターゲット、観測

function Subject() { 
 this.observes = new ObserveList();
}

// オブザーバーの追加

Subject.prototype.addObserve = function (observe) { 
 this.observes.add(observe)
}

//オブザーバのメソッドを削除します。

Subject.prototype.removeObserve = function (observe) { 
 this.observes.removeAt(this.observes.indexOf(observe, 0))
}

// オブザーバの値が変更されたら、適切なサブスクライバにイベントを通知します。

Subject.prototype.notify = function (context) { 
 let observeCount = this.observes.count();
 for(let i = 0; i < observeCount; i++) {
 this.observes.get(i).update(context)
 }
}

// オブザーバー

function ObserveGil() { 
 this.update = function (context) { 
 console.log('最初のガールフレンドは' + context)
 }
}
function ObserveGil1() { 
 this.update = function (context) { 
 console.log('2番目のガールフレンドは、' + context)
 }
}
function ObserveGil2() { 
 this.update = function (context) { 
 console.log('3人目のガールフレンドが' + context)
 }
}

// // 特定の用途

let mySubject = new Subject();
mySubject.addObserve(new ObserveGil());
mySubject.addObserve(new ObserveGil1());
mySubject.addObserve(new ObserveGil2());
mySubject.notify('今日は娼婦になる)

// パブリッシング購読者

let publish = {};
(function (myObject) { 
 // パブリッシング用のメッセージキューを定義する
 let topics = {};
 // 追加された各購読者に一意の識別子を追加する
 let subUid = -1;
 // 特定のサブスクリプションを発行する
 
 myObject.publish = function (topic, args) { 
 if (!topics[topic]) {
 return false
 }
 let subscribers = topics[topic];
 let len = subscribers ? subscribers.length : 0;
 while (len--) {
 subscribers[len].func(topic, args)
 } 
 return this;
 }
 // サブスクリプションセンターにサブスクリプションを追加する
 myObject.subscribe = function (topic, func) {
 // パブリッシュされたメッセージが存在するかどうかを検出し、存在しない場合はストアを作成する。
 if (!topics[topic]) {
 topics[topic] = []
 }
 // 一意の識別子を生成する
 let token = (++subUid).toString();
 topics[topic].push({
 token: token,
 func: func
 })
 return token;
 }
 // 再購読から購読を解除する
 myObject.unSubscribe = function (token) { 
 for (const key in topics) {
 if (topics.hasOwnProperty(key)) {
 const element = topics[key];
 for(let i = 0; i < element.length; i++) {
 if (element[i].token === token) {
 topics[key].splice(i, 1)
 return token
 }
 }
 }
 }
 return this
 }
})(publish);
publish.subscribe('test', () => {console.log('パブリッシュサブスクライバーのメソッドを登録し、実行する')});
publish.publish('test')
Read next

これでdockerへのnginxデプロイは終了だ。

次に以下のディレクトリを作成し、certが置かれるパス、htmlが置かれるパス、confが置かれるパス、ログが置かれるパスを指定してファイルを作成します。

May 26, 2020 · 2 min read