地下アイドルとアイドルオタクを疎結合にしてみたら、夢も希望もなくなった〜デザインパターンのObserverを考える〜

![idol_mikan_bako.png](https://qiita-image-store.s3.amazonaws.com/0/74851/faf8c20a-72ac-dff7-4e94-d986ffef3662.png)


# ある日の地下アイドル

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

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

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

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

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

### アイドルクラス

```javascript
/** アイドルクラス */
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();
}
```

### アイドルによる告知

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

### オタククラス

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

### 告知結果
```
みんなだいすき！CD買ってね！
takkunはCDをぜってーかうぜ！！
shinobunはCDをぜってーかうぜ！！
yukkiはCDをぜってーかうぜ！！
```

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

地ア「今日は１０人もライブに来てくれた！！」

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

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

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

### アイドルクラス

```javascript
/** アイドルクラス */
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();
}
```

### アイドルによる告知

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

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

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

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

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

![fbf38df386826864d02aee89bd7cc1ae.jpg](https://qiita-image-store.s3.amazonaws.com/0/74851/61465a30-c524-bd87-1917-1212e96ed64c.jpeg)


地ア「アアアアアアアアアアアアアアアアアアアアアア！！！！！！！」

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

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


![download.jpg](https://qiita-image-store.s3.amazonaws.com/0/74851/fe5fa00e-96b0-c7bf-29e9-c60ea46f6217.jpeg)


地ア「ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛ア゛！！！！！！！」


# どうしてこうなったのか

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

![Untitled (38).png](https://qiita-image-store.s3.amazonaws.com/0/74851/39e4abef-3bfa-31bd-b704-de9d22db6d71.png)

このままでは、

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

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

つまり、

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


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

地ア「そうだ！」

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


これがObserverパターンの始まりです（嘘）


# Observerパターンで書き直す

#### アイドルクラス

```javascript
/** アイドルクラス */
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の名前が全て消えました。

![Untitled(1) (15).png](https://qiita-image-store.s3.amazonaws.com/0/74851/c6c7ef95-f185-dc18-fb80-83125b017b4f.png)


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

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

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

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

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

# 使い方

```javascript
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を買ってくれる人ならだれでも通知することが出来ます。

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

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

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


# まとめ１

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

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


# まとめ２

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

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

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

夢も希望もなくなる感じになりました。