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

2014-11-24 08:27:02 · 作者: · 浏览: 6
tate) {
15. /**
16. * 更新观察者的状态,使其与目标的状态保持一致
17. */
18. observerState = state;
19. System.out.println("状态为:" + observerState);
20. }
21.
22. }


  客户端类
[java]
1. package com.bankht.Observer;
2.
3. /**
4. * @author: 特种兵—AK47
5. * @创建时间:2012-6-28 下午09:56:04
6. *
7. * @类说明 :客户端类
8. */
9. public class Client {
10.
11. public static void main(String[] args) {
12. // 创建主题对象
13. ConcreteSubject subject = new ConcreteSubject();
14. // 创建观察者对象
15. Observer observer = new ConcreteObserver();
16. // 将观察者对象登记到主题对象上
17. subject.attach(observer);
18. // subject.detach(observer);
19. // 改变主题对象的状态
20. subject.change("new state");
21. }
22.
23. }

 运行结果如下:
[html]
1. Attached an observer
2. 主题状态为:new state
3. 状态为:new state


  在运行时,这个客户端首先创建了具体主题类的实例,以及一个观察者对象。然后,它调用主题对象的attach()方法,将这个观察者对象向主题对象登记,也就是将它加入到主题对象的聚集中去。
  这时,客户端调用主题的change()方法,改变了主题对象的内部状态。主题对象在状态发生变化时,调用超类的notifyObservers()方法,通知所有登记过的观察者对象。
推模型和拉模型
  在观察者模式中,又分为推模型和拉模型两种方式。
  ●  推模型
     主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。
  ●  拉模型
     主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。一般这种模型的实现中,会把主题对象自身通过update()方法传递给观察者,这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。
  根据上面的描述,发现前面的例子就是典型的推模型,下面给出一个拉模型的实例。
  拉模型的抽象观察者类
  拉模型通常都是把主题对象当做参数传递。
[java]
1. package com.bankht.Observer.pull;
2.
3. /**
4. * @author: 特种兵—AK47
5. * @创建时间:2012-6-28 下午10:03:02
6. *
7. * @类说明 :拉模型通常都是把主题对象当做参数传递。
8. */
9. public interface Observer {
10. /**
11. * 更新接口
12. *
13. * @param subject
14. * 传入主题对象,方面获取相应的主题对象的状态
15. */
16. public void update(Subject subject);
17. }


  拉模型的具体观察者类
[java]
1. package com.bankht.Observer.pull;
2.
3. /**
4. * @author: 特种兵—AK47
5. * @创建时间:2012-6-28 下午10:03:25
6. *
7. * @类说明 : 拉模型的具体观察者类
8. */
9. public class ConcreteObserver implements Observer {
10. // 观察者的状态
11. private String observerState;
12.
13. @Override
14. public void update(Subject subject) {
15. /**
16. * 更新观察者的状态,使其与目标的状态保持一致
17. */
18. observerState = ((ConcreteSubject) subject).getState();
19. System.out.println("观察者状态为:" + observerState);
20. }
21.
22. }


  拉模型的抽象主题类
  拉模型的抽象主题类主要的改变是nodifyObservers()方法。在循环通知观察者的时候,也就是循环调用观察者的update()方法的时候,传入的参数不同了。
[java]
1. package com.bankht.Observer.pull;
2.
3. import java.util.ArrayList;
4. import java.util.List;
5.
6. /**
7. * @author: 特种兵—AK47
8. * @创建时间:2012-6-28 下午10:03:48
9. *
10. * @类说明
11. * :拉模型的抽象主题类主要的改变是nodifyObservers()方法。在循环通知观察者的时候,也就是循环调用观察者的update()方法的时候,
12. * 传入的参数不同了。
13. */
14. public abstract class Subject {
15. /**
16. * 用来保存注册的观察者对象
17. */
18. private List list = new ArrayList();
19.
20. /**
21. * 注册观察者对象
22. *
23. * @param observer
24. * 观察者对象
25. */
26. public void attach(Observer observer) {
27.
28. list.add(observer);
29. System.out.println("Attached an observer");
30. }
31.
32. /**
33. * 删除观察者对象
34. *
35. * @param observer
36. * 观察者对象
37. */
38. public void detach(Observer observer) {
39.
40. list.remove(observer);