观察者模式(Observer Pattern)是一种行为模式(Behavior Design Patters)。观察者模式建立了对象之间的依赖关系(Dependency);一旦一个对象的状态发生变化,观察者模式能够通知依赖对象。在观察者模式下,一个对象可以同时"观察"多个对象;一个对象也可以同时被多个对象"观察"。
观察者模式的应用场景非常广。一个常见的例子是,在一个电子商务网站上,用户可以将商品添加入购物车(但未购买)。当商品的数量或者价格发生变化时,系统会通知这些用户,告知数量和价格的变更。
在观察者模式中,有四个参与方。
图一 观察者模式结构。
我们使用一个简单的用例来展示观察者模式的用法。这个用例实现了一个简单的,跟踪商品价格的功能。当商品的价格发生变化时,系统会通知用户。
我们首先定义一个Subject接口,用于定义观察者注册(registerObserver)和注销(removeObserver)接口,通知用户接口(notify)和设置价格接口(setPrice)。在Product类中实现了这些接口。Product对象将所有关心该商品价格的用户放置在一个链表中(observers)。当价格发生变化后,通知所有注册了的用户。
interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notify();
public void setPrice(double newPrice);
}
public class Product implements Subject {
private ArrayList<Observer> observers = null;
private String name = null;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
this.observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notify() {
for(Observer observer: observers) {
observer.update(this.name, this.price);
}
}
@Override
public void setPrice(double newPrice) {
this.price = newPrice;
this.notify();
}
}
然后,我们定义观察者接口Observer,它只有一个成员方法update()。User类实现了Observer接口,在update()方法中实现处理新价格的逻辑。
interface Observer {
public void update(String productName, double productPrice);
}
public class User implements Observer {
@Override
public void update(String productName, double productPrice) {
// 收到了商品新的价格
}
}
最后,我们在ObserverPatternExample类中展示观察者模式的使用方法。首先,我们创建了两个用户UserA和UserB,和两个商品productA和productB。然后,将关心商品价格的用户注册到该商品中。最后,在修改商品的价格的同时,该程序会通知相应用户新的商品价格。
public class ObserverPatternExample {
public static void main(String[] args) {
User userA = new User();
User userB = new User();
Product productA = new Product("Book", 10.0);
productA.registerObserver(userA);
productA.registerObserver(userB);
Product productB = new Product("Magazine", 15.0);
productB.registerObserver(userA);
productA.setPrice(10.5); // 会通知userA和userB新的商品价格
productB.setPrice(14.5); // 会通知userA新的商品价格
}
}
本章介绍了观察者模式的结构和使用方法。观察者模式将事件的发生对象与接收对象分离开,使得开发人员可以专注于事件的触发逻辑和事件的响应逻辑。另外,从代码中可以看出,在事件发生时,观察者模式是依次通知观察者的。因此,在使用观察者模式时可能会出现一个观察者已经被通知,而另一个却尚未被通知的情况。
注册用户登陆后可留言