「Observer」デザインパターンがなんとなく分かるようになる話

##はじめに
こちらの記事は[GoFのデザインパターン](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))に基づいたObserverパターンについての解説になります。
Observerパターンを調べたけどイマイチよく分からんという方のために
具体的な実装例からイメージを掴めてもらえるような記事にしました。
※Observerの一般的な説明は[こちら](https://ja.wikipedia.org/wiki/Observer_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)

＜参考＞
[Java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030)
##Observerパターンとは
Observerとは、「観察者」という意味です。
すなわち、観察対象の状態が変化すると、観察者に対して通知がされます。
Observerパターンは、状態変化に応じた処理を記述するときに有効です。

##サンプルプログラムの構成
|クラス名  　|説明                  |
|----------|--------------------------|
|Observer  |観察者を表すインターフェース         |
|NumberGenerator|数を生成するオブジェクトを表す抽象クラス|
|RandomNumberGenerator|ランダムに数を生成するクラス|
|DigitObserver|数字で数を表示するクラス|
|GraphObserver|簡易グラフで数を表示するクラス|
|Main|動作テスト用のクラス|

##Observerインターフェース
「観察者」を表現するインターフェース

```Java
public interface Observer {
    public abstract void update(NumberGenerator generator);
}
```

・updateメソッドはNumberGeneretorクラスで呼び出される


##NumberGeneratorクラス
数を生成するオブジェクトを表す抽象クラス

```Java
import java.util.ArrayList;
import java.util.Iterator;

public abstract class NumberGenerator {
	private ArrayList observers = new ArrayList();

    // Observerを追加する
	public void addObserver(Observer observer) {
		observers.add(observer);
	}
    // Observerを削除する
	public void deleteObserver(Observer observer) {
		observers.remove(observer);
	}
    // Observer全員に対して「私の内容が更新されたので、あなたの表示を更新して下さい」と伝える
	public void notifyObserver() {
		Iterator it = observers.iterator();
		while(it.hasNext()) {
			Observer o = (Observer)it.next();
			o.update(this);
		}
	}

    // 数を取得する
	public abstract int getNumber();
    // 数を生成する
	public abstract void execute();
}
```
・Observerへ通知するnotifyObserver()の中でupdateメソッドを呼ぶことで、
　Observer全員に対して表示を更新するように伝えている


##RandomNumberGeneratorクラス
NumberGeneratorのサブクラスで乱数を生成するクラス

```Java   
import java.util.Random;

public class RandomNumberGenerator extends NumberGenerator {
    // 乱数を発生させる
	private Random random = new Random();
    // 現在の数
	private int number;
    // 数を取得する
	public int getNumber() {
		return number;
	}

	public void execute() {
		for (int i = 0; i < 20; i++) {
			number = random.nextInt(50);
			notifyObserver();
		}
	}
}
```

・executeメソッドは乱数を20個生成し、
　生成する毎にnotifyObserver()を使って、観察者に通知する。


##DigitObserverクラス
観察した数を数字で表示するクラス
Observerインターフェースを実装

```Java
public class DigitObserver implements Observer{
	public void update(NumberGenerator generator) {
		System.out.println("DigitObserver:" + generator.getNumber());
        // sleepは表示を見やすくするためにつけている
		try {
			Thread.sleep(1000);
		} catch(InterruptedException e) {
		}
	}
}
```

・updateメソッドを実装

##GraphObserverクラス
観察した数を*****のような表現で表示をするクラス
Observerインターフェースを実装

```Java
public class GraphObserver implements Observer{
	public void update(NumberGenerator generator) {
		System.out.print("GraphObserver:");
		int count = generator.getNumber();
		for (int i = 0; i < count; i++) {
			System.out.print("*");
		}
		System.out.println("");
        // sleepは表示を見やすくするためにつけている
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
		}
	}
}
```

・updateメソッドを実装

##Mainクラス
動作テスト用のクラス

```Java
public class Main {
	public static void main(String[] args) {
		NumberGenerator generator = new RandomNumberGenerator()	;
		Observer observer1 = new DigitObserver();
		Observer observer2 = new GraphObserver();
		generator.addObserver(observer1);
		generator.addObserver(observer2);
		generator.execute();
	}
}
```

###実行結果

```Java
DigitObserver:7
GraphObserver:*******
DigitObserver:1
GraphObserver:*
DigitObserver:9
GraphObserver:*********
DigitObserver:3
GraphObserver:***
DigitObserver:12
GraphObserver:************
(以下略)
```



##プログラムの解説
状態を持っているRandomNumberGeneratorクラスがあって、
乱数が生成されると、状態が変わったということでnotifyObserver()を呼び出します。
norifyObserver()が呼び出され、各Observerそれぞれが持つ実装されたupdateメソッドが実行されます。

##「観察」ではなく「通知」
Observerは観察者という意味なので、変更を「観察」していると考えられますが、
実際の動きを見ると能動的に観察しているわけではなく、
状態が変わったと「通知」されるのを受動的に待っているような作りとなっています。

開発をしているとよく遭遇するデザインパターンなので、
具体的な実装例からなんとなくでもイメージを掴めてもらえると嬉しいです。