最初にシーンを見てみる
多くのビジネスにはプロセス型のビジネスがあります。たとえば、オンライン ショッピング モール システムの注文操作には、次のようなプロセスが含まれる場合があります。
- 在庫を確認する
- 在庫の控除
- 注文の生成
- ユーザーに通知する
- 販売者に通知する
簡単な実装
最も直接的かつ簡単な方法は、現在のビジネスのニーズに応じて注文を行う操作で、在庫チェック、在庫ノッチ、注文生成、ユーザー通知、マーチャント通知などの API を呼び出すことです。それからそれをやり遂げてください。
既存の問題
この方法の問題は、特定のプロセスで新しい操作を追加する必要がある場合、
たとえば在庫を差し引いた後、在庫差し引きの結果をログ ファイルに書き込む操作を追加する必要があることです。
次に、注文の操作を変更し、この操作を注文の操作に追加する必要があります。
これにより、発注操作がますます複雑になり、メンテナンスが困難になります。
このようなコードは保守が困難になり、拡張にも役立ちません。変化をよりよく受け入れるために、これらのプロセスと注文の操作をどのように分離するか? このような問題を解決できるのがオブザーバーモードです。
解決
この問題を解決するには、Observer パターンを使用できます。オブザーバー パターン
(Observer Pattern): サブスクリプション発行パターンとも呼ばれ、オブジェクト間の 1 対多の依存関係を定義します。オブジェクトの状態が変化すると、依存するすべてのオブジェクトがオブジェクトは自動的に通知され、更新されます。
上記のシナリオでは、発注操作をサブジェクトとして使用し、在庫チェック、在庫控除、注文生成、ユーザー通知、販売者通知などの操作をオブザーバーとして使用できます。オーダー操作が発生すると、すべてのオブザーバーに通知が送信され、独自の操作が実行されます。
このようにして、プロセスを追加または削除する必要がある場合、発注操作を変更する必要はなく、オブザーバーのリストを追加または削除するだけで済みます。要件の変更も簡単に解決できます。
オブザーバー パターンのクラス図表現
簡単な理解
- オブザーバーはオブザーバー インターフェイスを継承し、update メソッドを実装します。
- 監視対象オブジェクトは、監視対象オブジェクト インターフェイスを継承し、アタッチ、デタッチ、および通知メソッドを実装します。
- 観測オブジェクトは観測者のリストを保持しており、観測オブジェクトが変更されるとすべての観測者に通知されます。
- 被观察者的变化会触发观察者的update方法,观察者可以根据自己的需求来实现update方法。
代码实现
观察者接口
//观察者接口
public interface Observer {
void update(Subject subject);
}
//被观察者接口
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
public class OrderService implements Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(this);
}
}
public void createOrder() {
System.out.println("创建订单");
notifyObservers();
}
}
public class ObserverOne implements Observer {
public void update(Subject subject) {
System.out.println("观察者收到通知,执行自己的操作");
}
}
public class ObserverTest {
public static void main(String[] args) {
OrderService orderService = new OrderService();
ObserverOne observerOne = new ObserverOne();
orderService.attach(observerOne);
orderService.createOrder();
}
}
优缺点
优点
- 观察者和被观察者之间是抽象耦合的。
- 建立一套触发机制。
- 观察者模式支持广播通信。
- 观察者模式符合“开闭原则”。
缺点
- 如果一个被观察者有很多直接和间接的观察者时,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和被观察者之间有循环依赖,观察者会等待被观察者处理完再处理,将导致系统崩溃。
- 观察者之间有过多的细节依赖,提高时间消耗及程序复杂度。
应用场景
- 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。
- 事件多级触发场景。
- 跨系统的消息交换场景,如消息队列的处理机制。