我目前正在使用
Java的Observer / Observable Pattern,我想知道:
为什么在当前的实现中需要 setChanged()方法?我知道它就在这里,所以我们只需要在治疗结束时拨打一次 notifyObservers().
为什么在当前的实现中需要 setChanged()方法?我知道它就在这里,所以我们只需要在治疗结束时拨打一次 notifyObservers().
这样,如果我们想要,我们可以使用clearChanged()回滚任何更改.但是,我们仍然可以在我们自己的实现中进行所有检查,并且只在我们绝对想要更新Observers时调用notifyObservers().
我可能错过了一些东西,但我不明白他们为什么不这样简化它.有任何想法吗?
解决方法
目的是将不同的问题分开.可以在一个地方调用通知观察者,同时跟踪另一个地方发生的变化.也许在某些情况下,您不需要这种分离,但java.util.Observable实现旨在处理复杂的情况,您不一定在更改和通知之间具有1-1对应关系.
例如,您可能需要限制通知以避免使用事件充斥客户端,这不会影响跟踪更改.下面的示例使用工作线程定期调用通知方法但不知道更改,以及其他接受更改但不处理通知的代码.
import java.util.*; public class ObservableExample { public static void main(String[] args) throws Exception { CountTracker t = new CountTracker(); t.addObserver(new Observer() { public void update(Observable observable,Object arg) { System.out.println("observed " + arg); } }); t.startNotifying(); for (int i = 0; i < 100; i++) { Thread.sleep(100L); t.incrementCount(); } t.quitNotifying(); System.out.println("done"); } } class CountTracker extends Observable { private int count = 0; private Thread notificationThread; public synchronized void incrementCount() { count++; setChanged(); } public synchronized void startNotifying() { if (notificationThread == null || !notificationThread.isAlive()) { notificationThread = new Thread(new Runnable() { public void run() { try { while (!Thread.currentThread().isInterrupted()) { Thread.sleep(1000L); String event = "current value of count is " + CountTracker.this.count; CountTracker.this.notifyObservers(event); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }); notificationThread.start(); } } public synchronized void quitNotifying() throws InterruptedException { if (notificationThread == null || !notificationThread.isAlive()) { return; } notificationThread.interrupt(); System.out.println("wait for notification thread to terminate"); notificationThread.join(); } }
类似于此的现实示例将是实现进度条,其需要将表示完成任务的累积输入转换为完成百分比并且决定更新UI显示的频率.
还要考虑你总是可以继承java.util.Observable. JDK库开发人员不希望必须支持大量的子专业化,因此他们倾向于创建尽可能广泛有用的类,但如果你想消除一些使用它的冗余,你可以创建自己的变异.