Шаблоны проектирования Java — шаблон наблюдателя

Шаблоны проектирования

Авторские права принадлежат автору Для любой формы перепечатки, пожалуйста, свяжитесь с автором для получения разрешения и укажите источник.

Что такое шаблон наблюдателя и его определение

Шаблон наблюдателя определяет отношение зависимости «один ко многим», позволяя нескольким объектам-наблюдателям одновременно отслеживать объект-субъект.Когда объект-субъект изменяется в состоянии, он уведомляет все объекты-наблюдатели, чтобы они могли автоматически обновлять себя.

Компоненты шаблона наблюдателя

Режим наблюдателя в основном состоит из следующих четырех ролей, а именно роли абстрактного субъекта, роли абстрактного наблюдателя, роли конкретного субъекта и роли конкретного наблюдателя.

абстрактная тематическая роль

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

роль абстрактного наблюдателя

Определите интерфейс для всех конкретных наблюдателей, которые обновляются при уведомлении субъекта.

конкретные предметные роли

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

конкретная роль наблюдателя

Роль реализует интерфейс обновления, требуемый абстрактной ролью наблюдателя для согласования своего состояния с состоянием субъекта.При желании конкретная роль наблюдателя может иметь ссылку на конкретную роль субъекта, обычно реализуемую с помощью подкласса

Пример кода для шаблона наблюдателя

Абстрактные тематические роли:

public interface AbstractSubject {
    public void addObserver(AbstractObserver observer);
    public void removeObserver(AbstractObserver observer);
    public void notification();
}

Конкретные предметные роли:

public class ConcreteSubject implements AbstractSubject {
    List<AbstractObserver> list = new ArrayList<AbstractObserver>();
    @Override
    public void addObserver(AbstractObserver observer) {
        list.add(observer);
    }
    @Override
    public void removeObserver(AbstractObserver observer) {
        list.remove(observer);
    }
    # 状态改变了,所有观察者更新自己的界面
    @Override
    public void notification() {
        for (AbstractObserver abstractObserver : list) {
            abstractObserver.update();
        }
    }
}

Роль абстрактного наблюдателя:

public interface AbstractObserver {
    public void update();
}

тестовый класс

class Client {
    public static void main(String[] args) {
       #生成一个主题角色
        AbstractSubject subject = new ConcreteSubject();
        #为主题角色增加观察者对象,这里采用匿名内部类的方式,与AWT编程里的安装监听器类似
        subject.addObserver(new AbstractObserver() {
            @Override
            public void update() {
                System.out.println("A同学您的APP需要更新");
            }
        });
        subject.addObserver(new AbstractObserver() {
            @Override
            public void update() {
                System.out.println("B同学您的APP需要更新");
            }
        });
        subject.addObserver(new AbstractObserver() {
            @Override
            public void update() {
                System.out.println("C同学您的APP需要更新");
            }
        });
        subject.notification();
    }
}

Встроенная в Java структура шаблонов наблюдателей

Встроенная в Java структура шаблонов наблюдателей обеспечиваеткласс наблюдаемыйиНаблюдатель интерфейса:

Класс Observable соответствует роли абстрактного субъекта и внутренне поддерживает коллекцию Vector для хранения конкретной роли наблюдателя. Наблюдатель интерфейса соответствует абстрактной роли наблюдателя.

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

  1. Напишите класс (конкретная роль субъекта) для наследования Observable (абстрактная роль субъекта), просто напишите метод изменения (функция этого метода состоит в том, чтобы уведомить зарегистрированную конкретную роль субъекта об обновлении)
  2. Напишите класс (конкретная роль наблюдателя) для реализации Observer (роль абстрактного наблюдателя), просто реализуйте метод update (Observable o, Object arg)
  3. Напишите тестовый класс для тестирования

Кодовая боевая демонстрация

Конкретные предметные роли:

public class Watched extends Observable {
    #状态改变的时候调用已注册的观察者的update方法,让它们更新自己
    public void count(int number) {
        for (; number >= 0; number--) {
            try {
                Thread.sleep(1000);
                #告知变更
                setChanged();     
                 #通知所有与我相关的Observer
                notifyObservers(number);  
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Конкретные роли наблюдателя:

public class Watcher implements Observer {
    #当主题角色事件触发时,会调用所有已注册的具体观察者角色的update方法
    @Override
    public void update(Observable o, Object arg) {
        int number = (Integer) arg;
        System.out.println(number);
    }
}

Тестовый класс:

public class Client {
    public static void main(String[] args) {
        #创建主题角色
        Watched watched = new Watched();
        #创建观察者角色
        Observer watcher1 = new Watcher();
        #自实现
        Observer watcher2 = new Observer() {
            @Override
            public void update(Observable o, Object arg) {
                int number = (Integer) arg;
                if (0 == number) {
                    System.out.println("done");
                }
            }
        };
        watched.addObserver(watcher1);
        watched.addObserver(watcher2);
        watched.count(10);
    }
}

Краткое изложение структуры шаблона Java Observer

  • Наблюдается, чтобы наследоватьObservableсвоего рода
  • Когда наблюдатель уведомляет наблюдателя, т.При вызове метода notifyObservers обязательно сначала вызовите метод setChanged()., функция этого метода состоит в том, чтобы установить измененную логическую переменную в объекте в значение true, потому что notifyObservers должны сначала проверить, является ли переменная истинной, если она ложна, она не будет выполняться и будет возвращена напрямую.
  • В классе Observable есть два перегруженных метода notifyObservers.Параметр в методе с параметрами — второй параметр в методе update в интерфейсе Observer.notifyObservers(number);Параметр числовой переменной фактически передается в интерфейс наблюдателя.update(Observable o, Object arg)второго параметра arg.