Java观察者设计模式范例
观察者模式是一种软件设计模式,在这种模式中,一个称为主体的对象维护着依赖它的所有其他对象(主体)的列表。这些家属被称为观察者。如果主题(所有从属对象(观察者)的维护者)的状态发生更改,系统会自动通知它们。通常通过方法调用来完成。
何时使用观察者模式
通常在对象之间存在一对多关系时使用。
当一个对象需要更新时,如果另一个( 相关对象修改/更改其“行为”。
当对象的观察者数量未知时。
如何工作
通常,有一个主题.java一个文件,该文件包含对所有观察者进行添加、删除和更新的所有方法,或者只是初始化它们并在不同的.java文件中执行所有方法功能。按照惯例,还有一个观察者.java文件,其中包含每次主题更改时调用的update()方法。之后,我们必须创建实现Subject类或者Observer类的.java文件。请注意,对于类是实现Subject还是Observer类文件,它会有所不同。
现实生活中的例子
想想你最喜欢的会员服务。也许是健身房,或者是Netflix,或者是完全不同的东西。我们将在这个例子中使用Netflix,但基本上任何其他会员服务都可以。如果Netflix更改了每月会员的价格,而我们正在为此付费,那么它应该通知我们。事实上,它应该通知所有注册/订阅的人他们的服务。
Java观察者设计模式范例
Subject.java
public interface Subject { public double getCurrentPrice(); public void setNewPrice(double newPrice); public void addNewSubscriber(Observer newSuObserver); public void removeSubscriber(Observer unsubscriber); public void notifyAllSubscribers(); }
在主题.java我们将初始化我们将在中使用的方法订阅rabber.java我很快就会介绍给你的文件。这些方法处理添加、删除和每当主题状态更改时触发的消息。
Observer.java
public interface Observer { public void update(double price); }
这是我们的观察课。它有我们将在类中创建的update(double price)方法订阅observer.java文件。请注意:此方法将在每次订阅价格更改时调用。
SubscriptionGrabber.java
import java.util.*; public class SubscriptionGrabber implements Subject { private List<Observer> subscribers = new ArrayList<Observer>(); private double price; public SubscriptionGrabber() { subscribers = new ArrayList<Observer>(); } public double getCurrentPrice() { return price; } public void setNewPrice(double newPrice) { this.price = newPrice; notifyAllSubscribers(); } public void addNewSubscriber(Observer newSubscriber) { subscribers.add(newSubscriber); } public void removeSubscriber(Observer unsubscriber) { int indexOfUnsubscriber = subscribers.indexOf(unsubscriber); subscribers.remove(indexOfUnsubscriber); } public void notifyAllSubscribers() { for (Observer subscriber : subscribers){ subscriber.update(price); } } }
java文件使用Subject接口。请注意,在setNewPrice(double newPrice)方法中,我们在设置了新价格之后会通知用户。重要的是,我们要在价格变化后再做,因为如果我们有更多的代码块,这可能会成为一个问题。我们的addSubscriber(Observer newSubscriber)和removeSubscriber(Observer unsubscriber)只是在观察者列表中添加或者删除一个人。我们需要在我们的模式中有一个删除功能,因为我们的目标是只通知订阅者,或者换句话说,只通知使用我们服务的人。我们不需要通知那些不再使用我们服务的人。最后,这个.java文件中的最后一个方法只是在每个订阅服务器上调用update(double price)方法(我们还没有创建这个方法)。
SubscriptionObserver.java
public class SubscriptionObserver implements Observer { private double price; private Subject subscriberGrabber; private int subscriptionID; public SubscriptionObserver(Subject subscriptionGrabber) { this.subscriberGrabber = subscriptionGrabber; this.subscriptionID+=1; subscriberGrabber.addNewSubscriber(this); System.out.println("New Observer: " + this.subscriptionID); } public void update(double price) { System.out.println("Price changed from $" + this.price + " to $" + price); this.price = price; } }
这是实际上(最终)具有更新功能的.java文件。请注意我是如何其中放入打印语句的。这一点非常重要(在update方法中有一个print语句),因为我们需要直观地显示用户发生了什么。在构造函数方法中,参数总是一个空列表(我们将在下一个.java文件中看到),subscriptionGrabber将是我们的新列表,它将保存订阅服务器。在第9行,我们可以看到我们正在添加这个新的订户。
ObserverPattern.java
public class ObserverPattern { public static void main(String[] args) { SubscriptionGrabber subscriptionGrabber = new SubscriptionGrabber(); SubscriptionObserver subscriptionObserver = new SubscriptionObserver(subscriptionGrabber); SubscriptionObserver subscriptionObserver2 = new SubscriptionObserver(subscriptionGrabber); SubscriptionObserver subscriptionObserver3 = new SubscriptionObserver(subscriptionGrabber); subscriptionGrabber.setNewPrice(5); } }
我们在这里创建grabber(列表),然后将该列表作为一个参数传递给subscription observer变量中的构造函数参数。然后我们把订阅的新价格定为5美元。预期的结果将是通知所有用户价格确实已改为5美元。