觀察者模式定義了對(duì)象之間的1:N的依賴關(guān)系,當(dāng)一個(gè)被觀察對(duì)象的狀態(tài)改變時(shí)馋记,其N個(gè)觀察依賴對(duì)象都會(huì)得到通知和更新,這種設(shè)計(jì)模式在系統(tǒng)設(shè)計(jì)中也被稱為發(fā)布-訂閱模式鸽粉,廣泛應(yīng)用于系統(tǒng)解偶設(shè)計(jì)。
觀察者設(shè)計(jì)模式中,多個(gè)觀察者對(duì)象正在觀察特定的主題對(duì)象拨齐,當(dāng)主題對(duì)象內(nèi)部狀態(tài)發(fā)生變化時(shí),觀察者注冊(cè)到主題對(duì)象中獲得通知昨寞。
觀察者對(duì)象可以自由的從訂閱主題中注入與注銷瞻惋,達(dá)到系統(tǒng)松耦合的設(shè)計(jì)目的。
什么時(shí)候使用觀察者模式
在我們進(jìn)行系統(tǒng)設(shè)計(jì)的時(shí)候援岩,如果存在多個(gè)對(duì)象狀態(tài)變化依賴某一個(gè)特定主題對(duì)象內(nèi)部狀態(tài)變化的時(shí)候歼狼,則可以應(yīng)用觀察者模式。
首先需要明確我們的主題對(duì)象享怀,其次我們將觀察者注入并觀察其內(nèi)部狀態(tài)變更羽峰,我們可以采用主動(dòng)觀察其狀態(tài)變更行為或者被動(dòng)接受行為變更時(shí)的通知,觀察者當(dāng)觀察到變更時(shí)執(zhí)行各自的行為添瓷。
觀察者模式案例
在電子商務(wù)領(lǐng)域主要圍繞線上商品交易打造限寞,其中核心的模塊是訂單的生命周期,這個(gè)是觀察者模式應(yīng)用的典型場(chǎng)景仰坦,因?yàn)槲覀兊南到y(tǒng)服務(wù)需要在訂單的各個(gè)狀態(tài)變更時(shí)作出即時(shí)的內(nèi)部操作或者用戶服務(wù)等履植;如果我們應(yīng)用觀察者模式來訂閱訂單狀態(tài)變更事件那么會(huì)為系統(tǒng)降低模塊之間的代碼耦合度。
觀察者模式設(shè)計(jì)
- Order:觀察者觀察對(duì)象悄晃,案例圍繞Order的內(nèi)部狀態(tài)變更來設(shè)計(jì)的發(fā)布訂閱
- OrderUpdateManager:Order狀態(tài)維護(hù)對(duì)象玫霎,扮演即時(shí)通知的角色
- Observer:觀察者接口抽象,將其實(shí)現(xiàn)類對(duì)象注冊(cè)與注銷綁定至OrderUpdateManager
- DeliveredObserver:觀察者實(shí)現(xiàn)妈橄,觀察Order狀態(tài)變更庶近,作出相應(yīng)的應(yīng)對(duì)事件
Order.java
package com.iblog.pattern.observe;
public class Order {
public String id;
public Status status;
public enum Status {
RECEIVED,
AWAIT_PAYMENT,
PAYMENT_RECEIVED,
PROCESSING,
EXCEPTION,
SHIPPED,
DELIVERED
}
}
Observer.java
package com.iblog.pattern.observe;
public interface Observer {
void observe(Event event);
}
PaymentNotifyObserver.java
package com.iblog.pattern.observe;
public class PaymentNotifyObserver implements Observer {
@Override
public void observe(Event event) {
if (event.preStatus != Order.Status.RECEIVED) {
return;
}
System.out.println("notify the order owner to pay for order");
}
}
PaidFinalsObserver.java
package com.iblog.pattern.observe;
public class PaidFinalsObserver implements Observer {
@Override
public void observe(Event event) {
if (event.preStatus != Order.Status.AWAIT_PAYMENT) {
return;
}
System.out.println("user paid for order, notify finals to check bill");
}
}
ReceivedPaymentObserver.java
package com.iblog.pattern.observe;
public class ReceivedPaymentObserver implements Observer {
@Override
public void observe(Event event) {
if (event.preStatus != Order.Status.PAYMENT_RECEIVED) {
return;
}
System.out.println("received the payment of order, notify to process the order");
}
}
DeliveredObserver.java
package com.iblog.pattern.observe;
public class DeliveredObserver implements Observer {
@Override
public void observe(Event event) {
if (event.preStatus != Order.Status.SHIPPED) {
return;
}
System.out.println("order is delivered, notify use to check the package");
}
}
OrderUpdateManager.java
package com.iblog.pattern.observe;
import java.util.ArrayList;
import java.util.List;
public class OrderUpdateManager {
private final List<Observer> observers = new ArrayList<>();
private final Notifier notifier;
public OrderUpdateManager() {
this.notifier = new Notifier(observers);
}
public void register(Observer observer) {
synchronized (observers) {
observers.add(observer);
}
}
public void unregister(Observer observer) {
synchronized (observers) {
observers.remove(observer);
}
}
public void awaitPaidOrder(Order order) {
notifier.notify(order, Order.Status.AWAIT_PAYMENT, "paid order");
}
public void receivedOrder(Order order) {
notifier.notify(order, Order.Status.RECEIVED, "await payment");
}
public void paidOrder(Order order) {
notifier.notify(order, Order.Status.PAYMENT_RECEIVED, "will process order");
}
public void delivered(Order order) {
notifier.notify(order, Order.Status.SHIPPED, "delivered");
}
}
Event.java
package com.iblog.pattern.observe;
public class Event {
public final Order order;
public final Order.Status preStatus;
public final String message;
public Event(Order order, Order.Status preStatus, String message) {
this.order = order;
this.preStatus = preStatus;
this.message = message;
}
}
Notifier.java
package com.iblog.pattern.observe;
import java.util.List;
public class Notifier {
private final List<Observer> observers;
public Notifier(List<Observer> observers) {
this.observers = observers;
}
public void notify(Order order, Order.Status preStatus, String subject) {
for (Observer o : observers) {
o.observe(new Event(order, preStatus, subject));
}
}
}
MockTest.java
package com.iblog.pattern.observe;
public class MockTest {
public static void main(String[] args) {
Order order = new Order();
order.id = "1";
order.status = Order.Status.RECEIVED;
OrderUpdateManager manager = new OrderUpdateManager();
Observer observer1 = new PaymentNotifyObserver();
Observer observer2 = new PaidFinalsObserver();
Observer observer3 = new ReceivedPaymentObserver();
Observer observer4 = new DeliveredObserver();
manager.register(observer1);
manager.register(observer2);
manager.register(observer3);
manager.register(observer4);
order.status = Order.Status.AWAIT_PAYMENT;
manager.receivedOrder(order);
order.status = Order.Status.PAYMENT_RECEIVED;
manager.awaitPaidOrder(order);
order.status = Order.Status.PROCESSING;
manager.paidOrder(order);
order.status = Order.Status.DELIVERED;
manager.delivered(order);
}
}
輸出:
notify the order owner to pay for order
user paid for order, notify finals to check bill
received the payment of order, notify to process the order
order is delivered, notify use to check the package
Jdk中觀察者模式