класи observer

Типи Observer / Observable надають протокол, відповідно до якого будь-яку кількість об'єктів-спостерігачів Observer отримують повідомлення про







будь-які зміни або події, що відносяться до довільній кількості об'єктів Observable. Об'єкт Observable проводиться від підкласу Observable, завдяки чому можна вести список об'єктів Observer, повинні повідомляти про зміни в об'єкті Observable. Все об'єкти- "спостерігачі", що входять до списку, повинні реалізовувати інтерфейс Observer. Коли зі спостережуваним об'єктом відбуваються зміни, заслужи

вающие уваги, або трапляються деякі події, які становлять інтерес для Observer, викликається метод notifyObservers об'єкта Observable, який звертається до методу update для кожного з об'єктів Observer. Метод update інтерфейсу Observable виглядає наступним чином:

public abstract void update (Observable obj, Object arg)

Метод викликається, коли об'єкт Observable повинен повідомити спостерігачам про зміну або деяке подію. Параметр arg дає можливість передачі довільного об'єкта, що містить опис зміни або події в об'єкті Observer.

Механізм Observer / Observable проектувався з розрахунком на універсальність. Кожен клас Observable сам визначає, коли і за яких обставин повинен викликатися метод update об'єкта Observer.

Клас Observable реалізує методи для ведення списку об'єктів Observer, для установки прапора, який повідомляє про зміну об'єкта, а також для виклику методу update будь-якого з об'єктів Observer. Для ведення списку об'єктів Observer використовуються наступні методи:

public synchronized void addObserver (Observer o)

Додає аргумент o типу Observer до списку об'єктів-спостерігачів. public synchronized void deleteObserver (Observer o)

Видаляє аргумент o типу Observer зі списку об'єктів-спостерігачів. public synchronized void deleteObservers ()

Видаляє всі об'єкти Observer з присутніх користувачів. public synchronized int countObservers ()

Повертає кількість об'єктів-спостерігачів.

Наступні методи сповіщають об'єкти Observer про зміни, що відбулися:

public synchronized void notifyObservers (Object arg)

Повідомляє всі об'єкти Observer про те, що зі спостережуваним об'єктом щось сталося, після чого скидає прапор зміни об'єкта. Для кожного об'єкта-спостерігача, що входить в список, викликається його метод update, першим параметром якого є об'єкт Observable, а другим - arg.







public void notifyObservers ()

Наведений нижче приклад показує, як протокол Observer / Observable може застосовуватися для спостереження за користувачами, зареєстрованими в системі. Спочатку визначається клас Users, що розширює Observable:

public class Users extends Observable

private Hashtable loggedIn = new Hashtable ();

public void login (String name, String password)

// метод збуджує виключення BadUserException if (! PasswordValid (name, password)

throw new BadUserException (name);

UserState state = new UserState (name); loggedIn.put (name, state); setChanged ();

public void logout (UserState state)

Об'єкт Users містить список активних користувачів і для кожного з них заводить об'єкт UserState. Коли хто-небудь з користувачів входить в систему або припиняє роботу, то всім об'єктам Observer передається його об'єкт UserState. Метод notifyObservers розсилає повідомлення спостерігачам лише в разі зміни стану об'єкта, що спостерігається, так що ми повинні також викликати метод setChanged для Users, інакше notifyObservers нічого не зробить. Крім методу setChanged, існує ще два методи для роботи з прапором зміни стану: clearChanged позначає об'єкт Observable у незмінному вигляді, а hasChanged повертає логічне значення прапора.

Нижче показано, як може виглядати реалізація update для об'єкта Observer, постійно стежить за складом зареєстрованих користувачів:

public class Eye implements Observer

public Eye (Users users)

public void update (Observable users, Object whichState)

if (users! = watching)

throw new IllegalArgumentException ();

UserState state = (UserState) whichState;

addUser (state); // внести в список

removeUser (state); // видалити зі списку

Кожен об'єкт Eye спостерігає за конкретним об'єктом Users. Коли користувач входить в систему або припиняє роботу, об'єкт Eye сповіщається про це, оскільки в його конструкторі викликається метод addObserver для об'єкта User, в якому об'єкт Eye вказується в якості об'єкта-спостерігача. При виклику методу update відбувається

перевірка на правильність параметрів і зміна виведеної інформації в залежності від того, увійшов чи даний користувач в систему або вийшов.

Перевірка того, що відбувається з об'єктом UserState, в даному випадку виконується

просто. Втім, її можна уникнути - для цього слід замість самого об'єкта UserState передавати об'єкт-оболонку, який описує, що і з ким відбувається. Такий варіант виглядає наочніше і полегшує додавання нових можливостей без порушення існуючого програмного коду.

Механізм Observer / Observable частково нагадує механізм wait / notify для потоків, описаний на стор. Проте він відрізняється більшою гнучкістю і меншою кількістю обмежень. Механізм потоків гарантує, що синхронний доступ захистить програму від небажаних ефектів багатозадачності. Механізм спостереження дозволяє організувати між учасниками будь-який зв'язок, не залежну від використовуваних потоків. В обох механізмах передбачений постачальник інформації (Observable і об'єкт, що викликає notify) і її споживач (Obs e rver і об'єкт, що викликає wait), проте

вони задовольняють різні потреби. Використовуйте wait / notify, коли механізм повинен враховувати специфіку потоків, і Observer / Observable для більш загальних випадків.

Створіть реалізацію інтерфейсу Attributed, в якій механізм Observer / Observable

використовується для повідомлення спостерігачів про зміни, що відбуваються c об'єктами.







Схожі статті