Skip to content

Instantly share code, notes, and snippets.

@varmil
Last active November 14, 2018 06:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save varmil/ff3e8038a40aea6ee4d4 to your computer and use it in GitHub Desktop.
Save varmil/ff3e8038a40aea6ee4d4 to your computer and use it in GitHub Desktop.
古典的オブザーバパターンをいまさら基礎からみる【デザインパターン】 ref: https://qiita.com/varmil/items/8cd8fe9da510e31d940a
class Model
{
// データ変更時に呼ばれる
void DataChanged() {
// 変更後のデータを取得
var newData = this.GetData();
// ModelからViewを直接変更(MVC原則に違反しています!)
FooView.Update(newData);
}
}
/**
* UI側の内部実装を知らなくても、 Update() というインターフェースだけ合意がとれていれば実装可
* Oveservable側は、誰に観察されているかは知らなくて良い
* ただ、観察されているという事実と、自分の状態に変化があった場合に、NotifyObservers()を
* 呼び出して、すべてのObserverのUpdate()を呼び出してやるだけ
*/
class Model : Oveservable
{
// サボってpublic
public string Foo;
void DataChanged() {
Foo = this.GetData();
// 変更を監視者(Observer)へ通知
this.NotifyObservers();
}
}
// Observableのどの状態が変更されたのか、問い合わせるだけで良い
//(後述のPush型ならば引数から取れる)
class View : IObserver
{
public UILabel Label;
private Model dataSource;
public Model DataSource
{
set
{
// Subscribe, Add, RegisterObserver などメソッド名は色々
value.AddObserver(this);
dataSource = value;
}
}
// Pull型の場合 (Unityの場合この名前じゃ駄目だけど)
void Update()
{
Label.text = dataSource.Foo;
}
}
class Program
{
public Model Model;
public View View;
void Start()
{
View.DataSource = Model;
// ... modelのデータを変更するような処理 ...
}
}
// Push型の場合、Interfaceで型を指定しなければならない。
// 故に、全てのObserverクラスで型を一致させる必要がある。
// 一方で用途が限定されているときはシンプルに書ける
interface IObserver
{
void Update(String value);
}
// IObserverを実装した例(先のミニマルな例と見比べると違いがわかる)
void Update(string text)
{
Label.text = text;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment