Наблюдаемая реализация шаблонов в Java
В настоящее время я использую Java Observer / Observable Pattern, и мне было интересно: Зачем нужен методsetChanged () в его текущей реализации ? Я понимаю, что это здесь так, что мы должны только вызвать notifyObservers () один раз, в конце нашего лечения.
Таким образом, если мы хотим, мы можем откатить любые изменения с clearChanged(). Но все же, мы могли бы сделать все проверки в нашей собственной реализации, и только вызвать notifyObservers (), когда мы абсолютно хотят обновить наблюдателей.
Возможно, я что-то упустил, но я не понимаю, почему они не упростили это таким образом. Есть идеи?1 ответ:
Цель состоит в том, чтобы отделить отдельные проблемы друг от друга. Уведомляющие наблюдатели могут быть вызваны в одном месте, в то время как отслеживание изменений происходит в другом месте. Возможно, для некоторых случаев вам не нужно такое разделение, но java.утиль.Наблюдаемая реализация была разработана, чтобы иметь возможность обрабатывать сложные случаи, где вы не обязательно должны иметь соответствие 1-1 между изменениями и уведомлениями.
Например, вы можете иметь требование, чтобы ограничить ваши уведомления, чтобы избежать наводнение ваших клиентов событиями, которые не должны влиять на отслеживание изменений по мере их возникновения. В приведенном ниже примере используется рабочий поток, который периодически вызывает метод 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(); } }
Реальным примером, подобным этому, может быть реализация индикатора выполнения, который требует перевода накопленных входных данных, представляющих задачи, выполняемые в процентах завершения и принятия решения. как часто обновлять отображение пользовательского интерфейса.
Также учтите, что вы всегда можете подкласс java.утиль.Заметный. Разработчики библиотеки JDK не хотели поддерживать огромное количество подспециализаций вещей, поэтому они предпочитали создавать классы, которые были максимально полезны, но если вы хотите устранить некоторую избыточность в том, как вы используете ее, вы можете создать свою собственную вариацию.