Implementation of observable pattern in Java
I am currently using the observer / observable pattern of Java. I want to know:
In this way, if we want, we can use clearchanged () to roll back any changes However, we can still do all the checks in our own implementation and call notifyobservers () only when we absolutely want to update observers
I may have missed something, but I don't understand why they don't simplify it like this Any ideas?
Solution
The purpose is to separate different problems You can call notification observers in one place and track changes in another Maybe in some cases, you don't need this separation, but Java util. Observable implementation is designed to handle complex situations. You do not necessarily have a 1-1 correspondence between changes and notifications
For example, you may need to restrict notifications to avoid flooding the client with events, which does not affect tracking changes The following example uses a worker thread to periodically call a notification method without knowing the change, and other code that accepts the change but does not process the notification
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(); } }
A realistic example similar to this would be the implementation of a progress bar, which needs to convert the cumulative input representing the completed task to a percentage of completion and determine how often the UI display is updated
Also consider that you can always inherit Java util. Observable. JDK library developers do not want to have to support a large number of sub specialization, so they tend to create classes as widely and useful as possible, but if you want to eliminate some redundancy in using it, you can create your own variation