行为型模式之Observer模式

简介:

观察者模式(又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式)

观察者模式中,一个目标对象管理所有依赖于它的观察者对象,并且在它本身的状态改变时主动发出通知。

应用场景

拍卖会可以认为是观察者模式的一种,每个投标人都可以出价。拍卖师开始拍卖时,他观察是否有牌子举起出价。每次接受一个新的出价都改变了拍卖的当前价格,并且广播给所有的投标人。

在JDK中的应用

  • java.util.EventListener
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener
  • javax.faces.event.PhaseListener

参与角色

抽象主题(Subject):

抽象主题提供一个接口,可以增加和删除观察者对象;
Subject把所有观察者对象的引用保存到一个集合里,每个主题都可以有任何数量的观察者;

具体主题(ConcreteSubject):
存储有关状态,这些状态应与目标的状态保持一致;
将有关状态存入具体观察者对象;
在具体主题内部状态改变时,给所有登记过的观察者发出通知;
实现Observer的更新接口以使自身状态与目标的状态保持一致。

抽象观察者(Observer):
为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

具体观察者(ConcreteObserver):
实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

 

观察者模式的类图

观察者模式的意图是定义对象之间一对多的依赖关系,一个对象状态改变,其他相关联的对象就会得到通知并被自动更新。

观察者模式实例

在这个实例中,观察者能够注册此主题,任何在此主题上的内容提交导致的变化都会通知所有在注册的观察者。

Subject抽象主题:

1
2
3
4
5
6
7
8
9
10
11
12
public  interface  Subject {
     //注册观察者
     public  void  attach(Observer obs);
     //移除观察者
     public  void  detach(Observer obs);
     
     //通知观察者
     public  void  noticeObservers();
     //获得主题的更新信息
     public  String getUpdate();
     
}

  

Observer抽象订阅者:

1
2
3
4
5
6
7
8
9
10
public  interface  Observer {
 
     /**
      * 获取主题变化,由Observer触发
      */
     public  void  update();
     
     /**设置主题对象*/
     public  void  setSubject(Subject sbj);
}

  

ConcreteSubject具体主题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public  class  ConcreteSubject  implements  Subject{
 
     private  String message; //传递的消息体
     private  boolean  changed; //消息状态标识
     //存储注册的观察者集合
     private  List<Observer> observers;
     
     public  ConcreteSubject(){
         this .observers= new  ArrayList<Observer>();
     }
     
     /**
      * 这里的Subject可以是主题订阅,具体关系中的老师-学生等
      */
     @Override
     public  void  attach(Observer obs) { 
         if (obs== null )
             throw  new  NullPointerException( "Null Observer" );
         if (!observers.contains(obs))
             observers.add(obs);
     }
 
     @Override
     public  void  detach(Observer obs) {
         observers.remove(obs);
     }
 
     @Override
     public  void  noticeObservers() {
         List<Observer> temp= null ;
         /**
          * 防止观察者收到订阅以前由被观察者发出的消息
          */
         synchronized  (ConcreteSubject. class ) {
             if (!changed)
                 return ;
             temp= new  ArrayList<>( this .observers);
             this .changed= false ;
         }
         
         for (Observer obs:temp){
             /**调用观察者的方法*/
             obs.update();
         }
     }
 
     @Override
     public  String getUpdate() {
         return  this .message;
     }
     
     public  void  postMessage(String msg){
         this .message=msg;
         this .changed= true ;
         //通知到观察者
         noticeObservers();
     }
 
}

  

ConcreteObserver具体观察者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public  class  ConcreteObserver  implements  Observer{
     
     //此处用于标注不同的观察者
     private  String name;
     //消息结果字段
     private  String result;
     //设置主题
     private  Subject subject;
     
     public  ConcreteObserver(String name){
         this .name=name;
     }
 
     @Override
     public  void  update() {
         /**从主题那里取得消息更新*/
         result=subject.getUpdate();
         /**处理消息*/
         System.out.println(name+ " get message " +result);
     }
 
     //设置主题
     @Override
     public  void  setSubject(Subject sbj) {
         this .subject=sbj;
     }
 
}

 

发布-订阅实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public  class  OBClient {
 
     public  static  void  main(String[] args){
         ConcreteSubject sbj= new  ConcreteSubject();
     
         ConcreteObserver obs1= new  ConcreteObserver( "obs1" );
         ConcreteObserver obs2= new  ConcreteObserver( "obs2" );
         ConcreteObserver obs3= new  ConcreteObserver( "obs3" );
         
         /**注册到主题*/
         sbj.attach(obs1);
         sbj.attach(obs2);
         sbj.attach(obs3);
         
         /**设置被观察对象*/
         obs1.setSubject(sbj);
         obs2.setSubject(sbj);
         obs3.setSubject(sbj);
         
         /**发送消息*/
         sbj.postMessage( "hello world!" );
 
     }
     
}

测试结果:



本文转自邴越博客园博客,原文链接:http://www.cnblogs.com/binyue/p/3728485.html,如需转载请自行联系原作者

相关文章
|
7月前
|
设计模式
设计模式-观察者(发布订阅)模式
设计模式-观察者(发布订阅)模式
|
设计模式 Java Spring
设计模式~观察者模式(Observer)-11
它属于行为型模式的一种。观察者模式定义了一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听。当这个主题对象状态变化时,会通知所有观察者对象并作出相应处理逻辑。 目录
73 0
|
设计模式 存储
设计模式-观察者模式(Observer)
设计模式-观察者模式(Observer)
97 0
|
设计模式 Java
Java设计模式-观察者模式(Observer)
Java设计模式-观察者模式(Observer)
|
Java 程序员
行为型模式 - 观察者模式(Observer Pattern)
行为型模式 - 观察者模式(Observer Pattern)
|
设计模式 存储 前端开发
设计模式之「观察者」模式
设计模式之「观察者」模式
174 0
设计模式之「观察者」模式
|
设计模式 大数据
行为型-Observer
行为型设计模式主要解决的就是“类或对象之间的交互”问题。 原理及应用场景剖析 观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。在 GoF 的《设计模式》一书中,它的定义是这样的: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 翻译成中文就是:在对象之间
118 0
|
存储 设计模式 Java
浅谈JAVA设计模式之——观察者模式(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
185 0
浅谈JAVA设计模式之——观察者模式(Observer)
|
设计模式 JavaScript Java
Head First 设计模式 —— 02. 观察者 (Observer) 模式
Head First 设计模式 —— 02. 观察者 (Observer) 模式
284 0
观察者模式(Observer )
对象间的联动——观察者模式(一)对象间的联动——观察者模式(二)对象间的联动——观察者模式(三)对象间的联动——观察者模式(四)对象间的联动——观察者模式(五)对象间的联动——观察者模式(五)
764 0