Наблюдаемый на Яве - PullRequest
       27

Наблюдаемый на Яве

16 голосов
/ 01 сентября 2011

Я пытаюсь понять Наблюдателя и Наблюдаемое.

Вот пример, который я пытаюсь выяснить:

public class IntegerDataBag extends Observable implements Iterable<Integer> {

    private ArrayList<Integer> list= new ArrayList<Integer>();

    public void add(Integer i){
        list.add(i);
        setChanged();
        notifyObservers();
    }

    public Iterator<Integer> iterator(){
        return list.iterator();
    }

    public Integer remove (int index){
        if (index< list.size()){
            Integer i = list.remove(index);
            setChanged();
            notifyObservers();
            return i;
        }
        return null;
    }

}

public class IntegerAdder implements Observer {

    private IntegerDataBag bag;

    public IntegerAdder(IntegerDataBag bag) {
        this.bag = bag;
        bag.addObserver(this);
    }

    public void update(Observable o, Object arg) {
        if (o == bag) {
            System.out.println("The contents of the IntegerDataBag have changed");
        }
    }

}
  1. bag.addObserver() может быть сделано только потому, что IntegerDataBag расширяется Observable?

  2. Куда добавляется этот наблюдатель? Что создается и где?

  3. В чем разница между setChanged() и notifyObservers()?

  4. Я не понимаю update метод; что означает arg? Зачем мне проверять это o==bag? Зачем мне обновлять другую наблюдаемую?

  5. Зачем мне вообще нужен этот наблюдатель?

Ответы [ 9 ]

10 голосов
/ 01 сентября 2011
  1. Да. addObserver - это метод в абстрактном классе Observable. См. Наблюдаемый в документации по Java.
  2. Добавляется в список в Observable.
  3. Вызов notifyObservers ничего не будет делать, пока не будет установлен setChanged.
  4. Возможно, у вас есть несколько наблюдаемых в одном приложении.
  5. Observer - это общий шаблон проектирования. Обычный пример - когда у вас есть модель и несколько видов. Каждый вид является наблюдателем на модели; если модель изменяется, представления обновляются.
6 голосов
/ 01 сентября 2011

Давайте возьмем практический пример для шаблона Observer: Twitter.С помощью Твиттера мы можем следить за некоторыми другими людьми и читать все, что они пишут, практически в реальном времени.

Каждый пользователь Твиттера наблюдаемый .Вы можете добавить себя в качестве слушателя («Подписчик») и читать его / ее посты.Каждый пользователь Твиттера сделает «Уведомление Подписчиков» (notifyObservers).

Здесь мы делаем то же самое.Класс IntegerDataBag имеет возможность уведомлять другие классы, когда значение добавляется или удаляется из его внутренней сумки.Любой экземпляр (который реализует Observer) может зарегистрироваться в IntegerDataBag и будет получать сообщения через метод обратного вызова (update).

Короче говоря, мы делаем следующее:

  1. A наблюдатель (слушатель IntegerAdder) добавляет себя к наблюдаемой (IntegerDataBag)
  2. Что-то происходит в наблюдаемой и наблюдаемый уведомляет своих наблюдателей
  3. наблюдаемый будет вызывать методы обратного вызова всех реальных наблюдателей
  4. Наблюдатель теперь получил уведомление о событии и может использовать его

Надеюсь, это краткое описание поможет понять этот шаблон.


публикация / подписка - похожая модель: издатель похож на наблюдаемый, подписчик - на наблюдателя.И еще один практический пример: можно подписаться на газету, и издатель будет присылать газету до тех пор, пока вы не отмените подписку.

5 голосов
/ 01 сентября 2011

bag.addObserver () может быть сделан только потому, что IntegerDataBag расширяется Заметный

Правильно, Observable - это класс с методом addObserver().

Куда добавляется этот наблюдатель? что создается и где?

Класс Observer содержит List или Vector (в источнике JDK) из Observable объектов.

private Vector obs;

Вот где он хранится.

В чем разница между setChanged() и notifyObservers()?

setChanged() просто отмечает, что Observable изменено. notifyObservers() просто вызывает всех наблюдателей в списке на update() (передача измененного объекта Наблюдателю), только если для setChanged установлено значение true.

Я не понимаю метод обновления - что означает args? а также зачем мне проверять этот мешок ==, зачем мне обновлять другой наблюдаемый

Метод update() сообщает Observer, что ему необходимо выполнить обновление на основе полученных obj изменений. Это называется notifyObservers() от Observable.

Зачем мне вообще нужен этот наблюдатель?

Чтобы создать Listener для сценария, управляемого событиями, т. Е. Если вы хотите получать информацию об изменении ваших наблюдаемых объектов, то необходим Observer.

Чтение: GoF - Шаблон наблюдателя .

4 голосов
/ 01 сентября 2011

bag.addObserver () может быть выполнен только потому, что IntegerDataBag расширяется Заметный

Да.

2.Куда добавлен этот наблюдатель? что создается и где?

В связанный класс Observable, который расширяет ваш класс.

4.Я не понимаю метод обновления - что означает args?

Он вызывается, когда состояние наблюдаемого объекта изменилось. Аргументы - это параметр, переданный nofityObserver.

и зачем мне проверять эту сумку, зачем мне обновлять другую? наблюдаемый

Вам не нужно ничего проверять.

5.Почему мне все равно нужен этот наблюдатель?

Это очень полезный шаблон дизайна. Загляните в википедию статья .

EDIT: Я пропустил точку:

Чем отличаются setChanged () от notifyObservers ()?

setChanged () отмечает объект, сигнализирующий, что он изменился. notifyObservers отвечает за то, чтобы разбудить всех наблюдателей, слушающих наблюдаемый объект.

3 голосов
/ 01 сентября 2011

bag.addObserver () может быть выполнен только потому, что IntegerDataBag расширяет Observable?

Да, метод addObserver реализован в Observable.

Куда добавляется этот наблюдатель?что создается и где?

Наблюдатель добавляется в список наблюдателей, который объявлен в Observable как частный, поэтому он не виден в вашем подклассе.

В чем разница между setChanged () и notifyObservers ()?

При вызове notifyObservers() без первого вызова setChanged() уведомления не производятся.

Я не понимаю метод обновления - что означает args?и зачем мне проверять эту сумку, зачем мне обновлять другую наблюдаемую?

Один Observer может смотреть несколько Observables.Изучив первый параметр метода update, вы можете выяснить, какой наблюдатель уведомляет вас о чем-либо.

Зачем мне этот наблюдатель в любом случае?

Каждый раз, когда вы хотите, чтобы класс отправлял события другим классам, но вам не нужна прямая зависимость этого класса от его наблюдателей.

2 голосов
/ 01 сентября 2011

bag.addObserver () может быть выполнен только потому, что IntegerDataBag расширяет Observable?

Да, в этом весь смысл.

Где находится этот наблюдательбыть добавленным к?что создается и где?

Добавляет IntegerAdder в список классов, которые наблюдают IntegerDatabag за изменениями.С этого момента, если изменение произойдет в IntegerDataBag, оно уведомит IntegerAdder с помощью метода notifyObservers(), который запустит его метод update().

В чем разница между setChanged() и notifyObservers ()?

notifyObservers() вызывает метод update() каждого наблюдателя вашей наблюдаемой и используется для передачи информации этому методу.Что касается setChanged(), он помечает ваш объект как «измененный», так что метод hasChanged() теперь возвращает true ... Он используется для отслеживания изменений в вашем наблюдаемом классе.

Я не понимаю метод обновления - что означает args?

Метод update() унаследован от реализации интерфейса наблюдателя - его необходимо реализовать.Object arg - это необязательный аргумент, который вы можете передать методу через notifyObservers().

Почему мне нужно проверить этот пакет o ==, зачем мне обновлять другой наблюдаемый?

Поскольку наблюдатель может «наблюдать» более чем одну «наблюдаемую», вам необходимо убедиться, что действительно IntegerDatabag вызвало update(), следовательно, o==bag.

Зачем мне в любом случае нужен этот наблюдатель?

Вам нужен наблюдатель, чтобы отслеживать IntegerDataBag на предмет изменений.В вашем случае вы печатаете сообщение в консоли при изменении IntegerDatabag.Цель модели Observer / Observable - отслеживать изменения конкретных объектов, а затем обновлять программу на основе изменений.

2 голосов
/ 01 сентября 2011

Метод update () вызывается Observable.Этот метод вызывается вызовом notifyObservers (), который проходит через все наблюдатели и вызывает обновление для них.Это информирует наблюдателя о том, что объект, который они наблюдают, был изменен, и может быть выполнено определенное действие.Объект args - это то, что вы хотите, он может быть нулевым, но его можно использовать, чтобы сообщить наблюдателям, какой тип обновления только что произошел.

2 голосов
/ 01 сентября 2011

Шаблон наблюдателя похож на концепцию слушателей. Объект, который прослушивается, поддерживает запись всех своих слушателей. Например, класс монитора запаса может позволить объектам прослушивать определенное событие, например, уровень запаса, падающий ниже уровня предупреждения.

С точки зрения наблюдателя:

Звоните subscribe() или addEventListener() или тому подобное. Затем наблюдатель «уведомляется», когда событие действительно происходит, обычно посредством вызова функции в наблюдателе (функция-обработчик события).

с точки зрения наблюдаемой:

Объекты, желающие наблюдать наблюдаемый объект, регистрируют свой интерес, вызывая subscribe() или addEventListener(), как указано выше. Таким образом, наблюдаемая добавляет этих наблюдателей в массив, список или некоторую другую структуру данных.

Как только событие действительно происходит, слушатели получают уведомление, вызывая функцию-обработчик события в классе наблюдателей.

2 голосов
/ 01 сентября 2011

В ответ на ваши баллы.

  1. Да, вы правы

  2. Наблюдатель добавлен в список, поддерживаемый в наблюдаемом объекте

  3. Вам необходимо вызвать setChanged (), прежде чем уведомлять наблюдателей, иначе они не узнают, что объект изменился.Как только вы вызываете notifyObservers (), все obvserers уведомляются об изменении.Если вы сначала не вызовете setChanged, ваши наблюдатели не будут уведомлены.

  4. arg - это то, что вы хотели бы передать наблюдателям при вызове notifyObservers (arg);

...