Last active
November 14, 2018 06:38
-
-
Save varmil/ff3e8038a40aea6ee4d4 to your computer and use it in GitHub Desktop.
古典的オブザーバパターンをいまさら基礎からみる【デザインパターン】 ref: https://qiita.com/varmil/items/8cd8fe9da510e31d940a
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Model | |
{ | |
// データ変更時に呼ばれる | |
void DataChanged() { | |
// 変更後のデータを取得 | |
var newData = this.GetData(); | |
// ModelからViewを直接変更(MVC原則に違反しています!) | |
FooView.Update(newData); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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のデータを変更するような処理 ... | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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