Паттерн «Наблюдатель» в JAVA

Паттерны   26 декабря 2012  Автор статьи:  

В данной статье мы рассмотрим паттерн Observer (наблюдатель). Суть данного паттерна заключается в том, что если один объект изменил свое состояние, то все объекты, которые были подписаны на него, тоже изменят свое состояние. Observer следует применять в следующих случаях:

  • Если изменение затрагивает несколько объектов
  • Если поведение многих объектов зависит от одного состояния
  • Если требуется поддерживать соответствие между объектами
  • Для предотвращения сильных связей между объектами системы
    • Паттерн наблюдатель очень часто используется при написании GUI. В частности Observe используется в библиотеке Swing. Для того, чтобы создать своего наблюдателя необходимо реализовать интерфейс Observer(наблюдатель), у объекта, который будет отслеживать изменения, и инкапсулировать Observable(наблюдаемый) у класса, который будет производить интересующие нас изменения. Для того, чтобы реализовать интерфейс Observer достаточно реализовать один метод:

      public interface Observer {
      /**
      * Метод вызывается, когда происходят какие - то изменения
      * в наблюдаемом объекте, а именно наблюдаемый объект вызовет
      * notifyObservers, чтобы все наблюдатели
      * узнали об изменении.
      *
      * @param o наблюдаемый объект.
      * @param arg аргумент, переданный в notifyObservers
      */
      void update(Observable o, Object arg);
      }

      Сейчас реализуем следующую программу. Пусть у нас будет две формы, на одной из которых будет текстовое поле, в которое мы будем вводить какую — либо информацию, а во второй форме будет отображаться эта информация. Для решении этой задачи напишем три класса Solution(наша точка входа), InputForm и OutputForm. Начнем с класса Solution, данный класс будет просто создавать два JFrame и говорить, что OutputForm будет наблюдать за InputForm.

      public class Solution {
      public static void main(String[] args) {
      InputForm inputForm = new InputForm();
      OutputForm outputForm = new OutputForm();
      inputForm.addObserver(outputForm);
      }
      }

      Теперь реализуем класс OutputForm, данный класс наследуется от JFrame и реализует интерфейс Observer:

      public class OutputForm extends JFrame implements Observer {
      OutputForm()
      {
      setSize(500,500);
      setTitle("Наблюдатель");
      setVisible(true);
      }
      @Override
      public void update(Observable o, Object arg) {
      JOptionPane.showMessageDialog(null,arg);
      }
      }

      Теперь реализуем самый сложный класс InputForm. Данный класс должен реализовывать класс Observable, замечу, что это уже готовый класс, который готов к использованию. Небольшое неудобство происходит при вызове функции notifyObservers. Данная функция выполнит свое назначение только если наблюдаемый параметр изменен, т.е флаг внутри объекта класса Observable должен стоять true, но метод setChanged(), который устанавливает флаг является protected, таким образом только наследник этого класса имеет право обращаться к этому классу. Чтобы избежать неудобной для нас работы класса Observable при его создании переопределим метод notifyObservers. После этого, нам достаточно отследить событие изменения нашего текстового поля и вызвать notifyObservers:

      import javax.swing.*;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.util.Observable;
      import java.util.Observer;
      class InputForm extends JFrame {
      JTextField input= new JTextField(10);
      private Observable myObservable = new Observable()
      {
      public void notifyObservers(Object arg) {
      setChanged();
      super.notifyObservers(arg);
      }
      };
      public void addObserver(Observer o)
      {
      myObservable.addObserver(o);
      }

      InputForm()
      {
      input.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
      myObservable.notifyObservers(input.getText());
      }
      });
      setSize(500,500);
      setTitle("Наблюдаемая форма");
      add(input);
      setVisible(true);
      }
      }

  • Andrii96

    код то не рабочий, как тут тогда что то понять ??

Научиться программировать

  • на Delphi

  • на Java

  • на C++