Шаблон Observer Java

Требуется определить связь «один ко многим» между объектами таким образом, чтобы при изменении состояния одного объекта все связанные с ним объекты опове­щались об этом и автоматически изменяли свое состояние. В языке Java этот шаблон используется под названием Listener.

clip_image002

Рис. 5.13. Пример реализации шаблона Observer

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

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

/*пример # 34 : класссубъект, за которым следят все классы-наблюдатели :

Rectangle.java */

package chapt05.observer;

import java.util.*;

public class Rectangle {

private float width;

private float height;

private ArrayList<OperationObserver> observerList =

new ArrayList<OperationObserver>();

public Rectangle(float width, float height) {

this.width = width;

this.height = height;

}

public void addObserver(OperationObserver observer) {

observerList.add(observer);

}

public float getWidth() {

return width;

}

public float getHeight() {

return height;

}

public void setWidth(float width) {

this.width = width;

notifyObservers();

}

public void setHeight(float height) {

this.height = height;

notifyObservers();

}

private void notifyObservers() {

Iterator it = observerList.iterator();

while (it.hasNext()) {

((OperationObserver) it.next()).valueChanged(this);

}

}

public String toString() {

String s = "";

Iterator it = observerList.iterator();

while (it.hasNext()) {

s = s +

((OperationObserver) it.next()).toString() + ‘\n’;

}

return s;

}

}

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

/*пример # 35 : классы-наблюдатели : OperationObserver.java : Square.java :

Perimeter.java */

package chapt05.observer;

public abstract class OperationObserver {

public abstract float valueChanged(Rectangle observed);

}

package chapt05.observer;

public class Perimeter extends OperationObserver {

private float perimeter;

public float valueChanged(Rectangle observed) {

return perimeter =

2 * (observed.getWidth() + observed.getHeight());

}

public String toString() {

return "P = " + perimeter;

}

}

package chapt05.observer;

public class Square extends OperationObserver {

private float square;

public float valueChanged(Rectangle observed) {

return square =

observed.getWidth() * observed.getHeight();

}

public String toString() {

return "S = " + square;

}

}

/*пример # 36 : использование шаблона Observer : Main.java */

package chapt05.observer;

public class Main {

public static void main(String args[]) {

Rectangle observed = new Rectangle(5, 3);

System.out.println(observed.toString());

observed.addObserver(new Square());

observed.addObserver(new Perimeter());

observed.setWidth(10);

System.out.println(observed.toString());

observed.setHeight(8);

System.out.println(observed.toString());

}

}

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

1 комментарий »

 
  • Mikhail says:

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

 

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100