君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

地下アイドル「私、ぜったい売れっ子アイドルになるんだから!」で学ぶデザインパターン(Observer)〜アイドルとオタクを疎結合にしてみた〜

f:id:karoten512:20180226001228p:plain

ある日の地下アイドル

地ア「は〜あ。今日もライブは3人しかこなかったなぁ」

地ア「きょう来てくれたのは、たっくんと、しのぶんと、ゆっきーか」

地ア「この3人、いつも来てくれるんだよねぇ。大事にしなくちゃ」

地ア「私、ぜったいに売れっ子アイドルになるんだから!」

地ア「…そろそろCD発売だから、告知しよっと」

アイドルクラス

/** アイドルクラス */
function ChikaIdle() {
}

ChikaIdle.prototype.noticeCdRelease = function() {

  /** わたし、みんなの名前も顔も覚えてるよ! */
  var takkun   = new Otaku('takkun');
  var shinobun  = new Otaku('shinobun');
  var yukki = new Otaku('yukki');
  
  /** CD買って(はあと) */
  console.log('みんなだいすき!CD買ってね!');
  takkun.getCd();
  shinobun.getCd();
  yukki.getCd();
}

アイドルによる告知

var chikaIdle = new ChikaIdle();
chikaIdle.noticeCdRelease();

オタククラス

/** オタククラス */
function Otaku(name) {
    this.name = name;
}
Otaku.prototype.getCd = function() {
    console.log(this.name + 'はCDをぜってーかうぜ!!');
}

告知結果

みんなだいすき!CD買ってね!
takkunはCDをぜってーかうぜ!!
shinobunはCDをぜってーかうぜ!!
yukkiはCDをぜってーかうぜ!!

だんだん売れてきた地下アイドル

地ア「今日は10人もライブに来てくれた!!」

地ア「きょう来てくれたのは、たっくんと、しのぶんと、ゆっきーと、ちーくんと、るなくんと、、、」

地ア「ほげくんとほげくんとほげくんかぁ」

地ア「そろそろCD発売だから、また告知しよっと」

アイドルクラス

/** アイドルクラス */
function ChikaIdle() {
}
ChikaIdle.prototype.noticeCdRelease = function() {

  /** わたし、みんなの名前も顔も覚えてるよ! */
  var takkun   = new Otaku('takkun');
  var shinobun  = new Otaku('shinobun');
  var yukki = new Otaku('yukki');
  var chi = new Otaku('chi');
  var luna = new Otaku('luna');
  var hoge1 = new Otaku('hoge1');
  var hoge2 = new Otaku('hoge2');
  var hoge3 = new Otaku('hoge3');
  var hoge4 = new Otaku('hoge4');
  var hoge5 = new Otaku('hoge5');

  console.log('みんなだいすき!CD買ってね!');
  /** CD買って(はあと) */
  takkun.getCd();
  shinobun.getCd();
  yukki.getCd();
  chi.getCd();
  luna.getCd();
  hoge1.getCd();
  hoge2.getCd();
  hoge3.getCd();
  hoge4.getCd();
  hoge5.getCd();
}

アイドルによる告知

var chikaIdle = new ChikaIdle();
chikaIdle.noticeCdRelease();

メッチャ売れてきたアイドル

地ア「すごい!今日ははじめて箱(ライブハウスのこと)がいっぱいになったよ!」

地ア「200人も来てくれた!」

地ア「今日来てくれたのはたっくんと、しのぶんと、ゆっきーと、ちーくんと、るなくんと、、、」

f:id:karoten512:20180226003450j:plain

地ア「アアアアアアアアアアアアアアアアアアアアアア!!!!!!!」

しのぶん「地下アイドルちゃん!僕の事今日から、しのぶーって読んでね!」

/** アイドルクラス */
function ChikaIdle() {
}
ChikaIdle.prototype.noticeCdRelease = function() {
  /** わたし、みんなの名前も顔も覚えてるよ! */
  // var shinobun  = new Otaku('shinobun');
  var shinobu  = new Otaku('shinobu');
  // shinobun.getCd();
  shinobu.getCd();
}

f:id:karoten512:20180226003618j:plain

地ア「ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛!!!!!!!」

どうしてこうなったのか

地下アイドルがいろいろ知りすぎです。

f:id:karoten512:20180226004952p:plain

このままでは、

オタク達が増えるたびに地下アイドルクラスに変更が行われ、

オタク達のあだ名が変わるたびにまた、地下アイドルクラスに変更が行われます。

つまり、

地下アイドルクラスはめちゃくちゃ仕様変更に弱いクラスということになります。

その時、地下アイドルは気づいた

地ア「そうだ!」

地ア「私は別に、みんなの名前を覚えなくていいんだ!」

これがObserverパターンの始まりです(嘘)

Observerパターンで書き直す

アイドルクラス

/** アイドルクラス */
function ChikaIdle() {
    this.fans = [];
}

ChikaIdle.prototype.addFan = function(fan) {
    this.fans.push(fan);
}

ChikaIdle.prototype.noticeCdRelease = function() {
  console.log('みんなだいすき!CD買ってね!'); 
  /*
   * アイドルはファンの名前は誰も知らない。
   * 知っているのはCDを買ってくれるということだけ
   */
  this.fans.forEach(function(fan, index, fans) {
    fan.getCd();
  });
}

アイドルクラスから、

Otakuクラス、

Otakuの名前が全て消えました。

f:id:karoten512:20180226010800p:plain

アイドルが知っているのは、

fanが「getCd」というメソッドを持っていることだけです。

もう、アイドルはオタクの顔も名前も思い出せません。

知っているのは、「告知をしたら、CDを買ってくれる」というただ1つだけ。。。

アイドルとオタクが非常に疎結合な、良い設計になりました。

使い方

var chikaIdle = new ChikaIdle();

var takkun   = new Otaku('takkun');
var shinobun = new Otaku('shinobun');
var yukki    = new Otaku('yukki');
var chi      = new Otaku('chi');
var luna     = new Otaku('luna');
var hoge1    = new Otaku('hoge1');
var hoge2    = new Otaku('hoge2');
var hoge3    = new Otaku('hoge3');
var hoge4    = new Otaku('hoge4');
var hoge5    = new Otaku('hoge5');

chikaIdle.addFan(takkun);
chikaIdle.addFan(shinobun);
chikaIdle.addFan(yukki);
chikaIdle.addFan(chi);
chikaIdle.addFan(luna);
chikaIdle.addFan(hoge1);
chikaIdle.addFan(hoge2);
chikaIdle.addFan(hoge3);
chikaIdle.addFan(hoge4);
chikaIdle.addFan(hoge5);

chikaIdle.noticeCdRelease();

さらなるメリット

アイドルは、CDを買ってくれる人ならだれでも通知することが出来ます。

/** 一般ピーポークラス */
function IppanPeople(name) {
    this.name = name;
}
IppanPeople.prototype.getCd = function() {
    console.log(this.name + 'はちょっと興味があるからCDかうよ');
}

getCdメソッドを持つクラスをまとめて扱うことが出来ます。

疎結合にしたことにより、ポリモーフィズムも使えるようになりました。

まとめ1

Observerパターンは、通知する側とされる側を疎結合にする。

疎結合にした結果、ポリモーフィズムも使えるようになる。

まとめ2

アイドルとオタクを疎結合にすると、

アイドルはオタクの顔も名前も覚えなくなり、

知っているのは「告知をしたら、CDを買ってくれる」というただ1つだけという

夢も希望もなくなる感じになる。