《JAVA与模式》第18天―观察者模式 (三)

2014-11-24 08:27:02 · 作者: · 浏览: 3

41. }
42.
43. /**
44. * 通知所有注册的观察者对象
45. */
46. public void nodifyObservers() {
47.
48. for (Observer observer : list) {
49. observer.update(this);
50. }
51. }
52. }


  拉模型的具体主题类
  跟推模型相比,有一点变化,就是调用通知观察者的方法的时候,不需要传入参数了。
[java]
1. package com.bankht.Observer.pull;
2.
3. /**
4. * @author: 特种兵—AK47
5. * @创建时间:2012-6-28 下午10:04:24
6. *
7. * @类说明 :跟推模型相比,有一点变化,就是调用通知观察者的方法的时候,不需要传入参数了。
8. */
9. public class ConcreteSubject extends Subject {
10.
11. private String state;
12.
13. public String getState() {
14. return state;
15. }
16.
17. public void change(String newState) {
18. state = newState;
19. System.out.println("主题状态为:" + state);
20. // 状态发生改变,通知各个观察者
21. this.nodifyObservers();
22. }
23. }

还是用刚才的Client.java 测试一下:
[html]
1. Attached an observer
2. 主题状态为:new state
3. 观察者状态为:new state


  两种模式的比较
  ■  推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。
  ■  推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。

JAVA提供的对观察者模式的支持
  在JAVA语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。
  Observer接口
  这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。
[java]
1. public interface Observer {
2.
3. void update(Observable o, Object arg);
4. }


  Observable类
  被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
[java]
1. public class Observable {
2. private boolean changed = false;
3. private Vector obs;
4.
5. /** Construct an Observable with zero Observers. */
6.
7. public Observable() {
8. obs = new Vector();
9. }
10.
11. /**
12. * 将一个观察者添加到观察者聚集上面
13. */
14. public synchronized void addObserver(Observer o) {
15. if (o == null)
16. throw new NullPointerException();
17. if (!obs.contains(o)) {
18. obs.addElement(o);
19. }
20. }
21.
22. /**
23. * 将一个观察者从观察者聚集上删除
24. */
25. public synchronized void deleteObserver(Observer o) {
26. obs.removeElement(o);
27. }
28.
29. public void notifyObservers() {
30. notifyObservers(null);
31. }
32.
33. /**
34. * 如果本对象有变化(那时hasChanged 方法会返回true)
35. * 调用本方法通知所有登记的观察者,即调用它们的update()方法
36. * 传入this和arg作为参数
37. */
38. public void notifyObservers(Object arg) {
39.
40. Object[] arrLocal;
41.
42. synchronized (this) {
43.
44. if (!changed)
45. return;
46. arrLocal = obs.toArray();
47. clearChanged();
48. }
49.
50. for (int i = arrLocal.length-1; i>=0; i--)
51. ((Observer)arrLocal[i]).update(this, arg);
52. }
53.
54. /**
55. * 将观察者聚集清空
56. */
57. public synchronized void deleteObservers() {
58. obs.removeAllElements();
59. }
60.
61. /**
62. * 将“已变化