Observer Pattern
What is Observer Pattern?
あるクラスが変化すると、別のクラスのパターンを検出して通知することで、あるオブジェクトの状態が変化するたびに、対応する動作が必要になる場合に、傍観者パターンを使用することができる.
->プログラムの場合、そのプログラムの値が変化しているため、すぐにフィードバックする必要があります.
Observer Pattern
- One of the Behavioural Patterns
動作モード
オブジェクトまたはクラス間のアルゴリズムまたは責任割当てモード
1つのオブジェクトで実行できない操作を複数のオブジェクトに割り当て、オブジェクト間の結合を最大限に低減し、モードがクラスに主に適用されるかオブジェクトに適用されるかによって区別します.
- It defines one-many relationship. So when one object changes its state, its dependents are notified.
あるオブジェクトの状態変化に応じて別のオブジェクトの状態を変化させ、一対のNオブジェクト間の依存関係を構成する設計モード.
- Pub-Sub Pattern
Pub-Sub Pattern
通知を受信するオブジェクト(Subscriber)とイベント励起オブジェクト(Publisher)の間にイベントチャネルを配置します.PublisherはSubscriberを知らない場合、イベント発生時にEvent Channelにメッセージを渡し、SubscriberもPublisherに関する情報がない場合は自分に合ったメッセージだけを送信します.(これは、応答を考慮せずに中間オブジェクトにまたがることができるため、非同期です.)
Observer Pattern == Pub-Sub Pattern
傍観者モードの場合、通知を受信した傍観者は、イベントを実行するマスターパブリッシャーに登録する必要があります.したがって、あるオブジェクトの状態が変化すると、そのオブジェクトに依存関係を持つ他のオブジェクトに通知され、情報更新の1対N関係が自動的に確立される.
->オブジェクト間に強い関係がある.これとは異なり、Pub-Subモードはより緩やかな関係を有する.
すなわち、2つのモードの最大の違いは、中間に Message Broker
またはEvent Bus
が存在するかどうかである.
ObserverモードはObserverとSubjectが相互に認識していることを示し,Pub-Subモードは互いを全く理解していなくても構わない.
SubjectにObserverを登録し、Subjectから直接Observerに通知します.
しかし、Pub-Subモードの場合、PublisherはSubscriberの位置や存在を知る必要はなく、メッセージキューなどのBrokerロールとしての中間点にメッセージを送信するだけでよい.SubscriberもPublisherの位置や存在を知る必要はなく、Brokerに割り当てられたタスクを監視し、割り当てられたタスクを受信するだけで、PublisherとSubscriberは互いの位置を知る必要はありません.
従って,Pub‐Subモードの結合度はObserverモードに比べて低かった.△依存性が低い.
観察者モードの多くは同期方式で動作するが,Pub−Subモードの多くは非同期方式で動作する.
なぜならBrokerは主にMessageQueueを使用しているからです.
Observerモードは単一ドメインで実装する必要があり、Pub-Subモードはドメイン間で実装することができる.
上記と同様に,アプリケーションのドメインが異なっていてもMessageQueueにアクセスできれば処理できる中間メディアBrokerがある.
Observerと比較したメリットとデメリット
Case of Observer Pattern
Apple Storeがあると仮定すると、周りには全部で5人のバイヤーがいて、そのうちの1人(A)はiPhone 13を購入したいと思っています.Aは毎回アップルストアにiPhone 13の在庫があるかどうかを見に行きます.この場合、1つの方法は、アップルストアにiPhone 13の在庫がある場合、周囲のバイヤーにメールを送ることです.この場合、このメッセージはAにとって適切なフィードバックであるかもしれないが、A以外の4人については適切なフィードバックではない.だから、これは良い接近とは言えない.
iPhone 13を購入したい購入者にのみメールを送るのが良い方法です.したがって、特定のイベントを購読するオブジェクトのみに対してイベント反応を行い、そのオブジェクトのみを理解することが望ましい.この方式は傍観者モードと呼ぶことができる.
△ニュース購読も同様の方法で行うことができる.
Basic Structure of Observer Pattern
Publisher
[]
Observers まず,観察者アレイについては,傍観者への参照を含むアレイである.3つの情報もあります.特定のpublisherのイベントを理解したい場合は、addObserverメソッドでこれらのイベントを追加し、ファイバアレイに参照を含めることができます.また、イベントへの反応を停止したい場合は、フィードバックなしにremoveObserverメソッドでアレイから削除できます.
最後のビジネスロジックでは、これらのコードは特定のイベントの開始時に実行されます.
Observer
傍観者はpublisherの活動に興味のある実体である.傍観者は主にいくつかある.
Protocol (Observer Protocol)
Publisherがこの更新と呼ばれる方法をどのように使用するかは、プロトコルによって理解できます.
When should you use Observer Pattern?
Whenever multiple entities are interested in the changes of state of an object, you can use Observer Pattern.
Example-購読サービス
前の例と同様に、サブスクリプションサービスでは、ファイバ・モードを使用してより効率的に管理できます.
3名の購読者に対してSubscriberとして指定し、1つのサービスに対してユーザーとして登録し(addObserverを介して)、状況に応じて購読をキャンセルしたユーザーはremoveObserverを使用できます.また,特定のアクティビティを受信した場合,サブスクリプションのユーザに特定のフィードバックのみを送信すればよい.
例えば、スモッグ濃度通知サービスを考えてみましょう.
上記の要素に従ってコードを記述します.以下に示します.protocol Observer: AnyObject {
func update(_ temp: Float, density: Float)
}
傍観者プロトコルを作成します.protocol Observable {
func addObserver(_ observer: Observer)
func removeObserver(_ observer: Observer)
}
class Publisher: Observable {
var observers = [Observer]()
func addObserver(_ observer: Observer) {
observers.append(observer)
}
func removeObserver(_ observer: Observer) {
observers = observers.filter({ $0 !== observer })
}
}
class DustMeter: Publisher {
var temperature: Float = 0.0
var density: Float = 0.0
func notify() {
for observer in observers {
observer.update(temperature, density: density)
}
}
}
Publisherでは、登録、削除、変更に対するフィードバックを実現します.class Subscriber: Observer {
var name: String = ""
init(name: String) {
self.name = name
}
func update(_ temp: Float, density: Float) {
print("\(name)님, 오늘의 온도는 \(temp)이고 미세먼지 농도는 \(density)이에요 😇")
}
}
次に、各傍観者に対して特定のイベントの更新関数を具体化する.class ViewController: UIViewController {
// MARK: - Properties
let dustMeter = DustMeter()
// MARK: - Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
// 관찰자
let user1 = Subscriber(name: "만수")
let user2 = Subscriber(name: "소연")
let _ = Subscriber(name: "만동")
// 알림을 받을 유저 추가
dustMeter.addObserver(user1)
dustMeter.addObserver(user2)
// 알림을 더이상 받지 않을 유저
dustMeter.removeObserver(user1)
}
// MARK: - IB Actions
@IBAction func touchUpButton(_ sender: Any) {
dustMeter.temperature = 32
dustMeter.density = 80
dustMeter.notify()
}
}
また、実際に使用する場合は上記のように使用することができます.
Reference
この問題について(Observer Pattern), 我々は、より多くの情報をここで見つけました
https://velog.io/@pcsoyeon/Observer-Pattern
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
protocol Observer: AnyObject {
func update(_ temp: Float, density: Float)
}
protocol Observable {
func addObserver(_ observer: Observer)
func removeObserver(_ observer: Observer)
}
class Publisher: Observable {
var observers = [Observer]()
func addObserver(_ observer: Observer) {
observers.append(observer)
}
func removeObserver(_ observer: Observer) {
observers = observers.filter({ $0 !== observer })
}
}
class DustMeter: Publisher {
var temperature: Float = 0.0
var density: Float = 0.0
func notify() {
for observer in observers {
observer.update(temperature, density: density)
}
}
}
class Subscriber: Observer {
var name: String = ""
init(name: String) {
self.name = name
}
func update(_ temp: Float, density: Float) {
print("\(name)님, 오늘의 온도는 \(temp)이고 미세먼지 농도는 \(density)이에요 😇")
}
}
class ViewController: UIViewController {
// MARK: - Properties
let dustMeter = DustMeter()
// MARK: - Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
// 관찰자
let user1 = Subscriber(name: "만수")
let user2 = Subscriber(name: "소연")
let _ = Subscriber(name: "만동")
// 알림을 받을 유저 추가
dustMeter.addObserver(user1)
dustMeter.addObserver(user2)
// 알림을 더이상 받지 않을 유저
dustMeter.removeObserver(user1)
}
// MARK: - IB Actions
@IBAction func touchUpButton(_ sender: Any) {
dustMeter.temperature = 32
dustMeter.density = 80
dustMeter.notify()
}
}
Reference
この問題について(Observer Pattern), 我々は、より多くの情報をここで見つけました https://velog.io/@pcsoyeon/Observer-Patternテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol