見出し画像

📈 Observerパターン コンポジットと集約 デザインパターンの宗祖

監察官ObserverパターンはSubject(Observable:イベントとか)を観察する

クラスの要素と図のみかたをUmletinoでおぼえる

https://www.umletino.com/

まずは継承(汎化)

汎化(inheritance)

javaだと継承に関する宣言子はAbstract /extendsなど

Javaプログラミング言語では、すべての変数と式は、コンパイル時に決定できる型を持っています。この型は、プリミティブ型であったり、参照型であったりします。参照型には、クラス型とインタフェース型があります。参照型は,クラス宣言(8.1節)とインタフェース宣言(9.1節)を含む型宣言によって導入されます.クラスやインタフェースを指して型という言葉を使うことがよくあります。

https://docs.oracle.com/javase/specs/jls/se18/html/jls-4.html#jls-4.12.6

抽象クラスは、不完全なクラス、または不完全とみなされるクラスである。

https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.1.1.1

クラスCは、その直接の上位クラス型Dから、次のすべてが真となるすべての具象メソッドm(静的およびインスタンスの両方)を継承する。

https://docs.oracle.com/javase/specs/jls/se18/html/jls-8.html#jls-8.4.8

継承(汎化)が議論に出てこないデザインパターン

Singleton(継承しないので)、Facade(モジュール粒度が違うので)、Flyweight(どっちでもいいので)、Memento(粒度)

継承の根拠になるのは置換可能性という概念

これは、オブジェクト(クラスなど)とサブオブジェクト(最初のクラスを拡張したクラスなど)は、プログラムを壊すことなく交換可能でなければならないとするものである。

https://en.wikipedia.org/wiki/Liskov_substitution_principle

汎化とちょっと違う実装(実現)線

実現(Realisation/implementation)

JavaだとInterface/Implementsなど

実装(implementation)が脚光を浴びるデザインパターン

Prototype(しめしあわせがある) Adapter(委譲or継承)、Command(TBD)、State(状態だから)、Strategy(たぶん継承委譲)、そしてこのObserverパターン

Observerパターンの議論に入る前に、コンポジットと集約について少し

集約と合成

つないだ先AとBで、Aが消滅してもBが消滅しないのが集約、Aが消滅したらBも消滅するのが合成。 合成には多重度の記述がある。

集約系パターン

Builder(頭領が大工を集約)、Bridge(橋渡しを集約)、Composite(子供を集約)、Decorator(コンポーネントをデコレータが集約)、FlightWeight(FWファクトリがフライトウェイトを集約)、Interpreter(表現を集約)、Iterator()、State(状態たくさん)、Strategy(戦略いくつか)、

合成系パターン

GofのObserver 集約まで書いてなく、汎化(継承)で組み上がっている

GOFのObserver 集約は無しで、汎化(継承)で組み上がっている

例えば、多くのグラフィカルユーザインタフェースツールキットは、ユーザインタフェースのプレゼンテーションの側面を、基礎となるアプリケーションデータから分離します。アプリケーションデータとプレゼンテーションを定義するクラスは、独立して再利用することができます。

https://amzn.to/3okBiw4

 イベント処理に関わる

あるオブジェクト(Observer)を変更すると他のオブジェクト(Observer)も変更しなければならないが、いくつのオブジェクト(Observer)を変更する必要があるかわからない場合

  • ObserverオブジェクトがSubjectを観察することができる。

  • SubjectはObserverオブジェクトをアタッチしたりデタッチするためのインタフェースを提供する。

  • Observerは観察できるようにする代わりに、Subjectに更新情報を与える

観察できるのはオブザーバー、観察させるのはサブジェクト

Subject(観察対象)=Observable(観察できるよ)という言い方もある

Observable - オブザーバをクライアントにアタッチ、デアタッチするための操作を定義するインターフェースまたは抽象クラスです。GOFブックでは、このクラス/インターフェイスはSubjectとして知られています。

https://stackoverflow.com/questions/32879672/in-observer-design-pattern-are-subject-and-observable-the-same-thing

つまり、あるアクションを聞いて、そのアクションが発生したことを知ることができるものはすべてObservableである。つまり、Event Listenerはそのひとつだ。なぜなら、イベントを聞くことができ、そのイベントが発生したことを即座に知らせてくれるからだ。個人的には、Observableと言われたら、イベントを思い浮かべます。

https://stackoverflow.com/questions/5941800/is-an-eventlistener-an-observable#:~:text=An%20Observable%20is%20simply%20an,you%20that%20they%20have%20happened.

Listener=Observerかは、文脈によるようだ

「リスナー」という用語がObserverパターンを指すかどうかは、文脈に依存します。例えば、Java Swing の「Event Listeners」は Observer パターンの実装の一部ですが、.Net の「Trace Listeners」はそうでありません。

https://stackoverflow.com/questions/3358622/observer-design-pattern-vs-listeners

Mediator & Observer

真ん中がMediatorで疎結合を促進

おまけ)デザインパターンの宗祖はChristopher AlexanderにあるとKhalidが言い出した。

この論文では、大都市の道路の新しいパターンについて述べている。このパターンに従ってレイアウトされたエリアの平均速度は、現在の都市部の典型的な15マイル(時速15マイル)に対して、45マイル(時速45マイル)になる。このパターンの主な特徴は次のとおりである:すべての通りが平行であること、交差する通りがないこと、通りは3マイル離れたフリーウェイで結ばれていること。

https://www.tandfonline.com/doi/abs/10.1080/01944366608978208


道路の建築についての話がデザインパターンの話となる。

それを拾った奇人が80年代に登場したと言うことらしい

90年代、GoFとデザインパターンが登場

クリストファー・アレクサンダーは、「それぞれのパターンは、私たちの環境で何度も何度も発生する問題を記述し、その問題に対する解決策の核心を、同じ方法を二度も行うことなく、この解決策を何百万回も繰り返し使用できるような方法で記述している」[AIS+77, page x}と述べています。

パターンを適用することで抽象度が上がっていく

話はSmalltalk-80のMVCに行く。つまり「デザインパターン」の議論とは、当初イベントやらVIewやらのUIの制御を前提としているということがわかる。上記をふまえて、Observerパターンをもいちど見る。

オブジェクト間の一対多の依存関係を定義し、あるオブジェクトの状態が変化したときに、その依存関係のすべてが通知され、自動的に更新されるようにします。

MVC の Model クラスは Subject の役割を果たし、View はオブザーバの基底クラスです。

Smalltalk、ET++ や THINK クラスライブラリは、システム内の他のすべてのクラスの親クラスに Subject と Observer のインターフェイスを置くことで、一般的な依存関係メカニズムを提供しています。

関連するパターンとしてMediatorとSingletonが挙げられている。Mediatorは文字通り仲介者として、Singletonは観察するクラスが一意性を持つためにそれぞれ関連がある。

コールバックを使うよりもオブザーバーにした方がネストが浅くなる

数式で見るオブザーバーパターン

オブザーバーパターンは、あるオブジェクト(サブジェクト)の状態が変化したときに、依存する他のオブジェクト(オブザーバー)に自動的に通知され、更新されるようにするパターンです。これは以下のような関数で表せます。

O=f(S)

ここで、Sはサブジェクトの状態、Oはオブザーバーの集合、fはサブジェクトの状態変化に応じてオブザーバーを更新する関数です。


お願い致します