设计模式——观察者模式

观察者模式(又称发布/订阅者模式)提供了避免组件之间紧密耦合的一种方法,将观察者和被观察者的对象分开。在该模式中,一个对象通过添加一个方法使自身变得可观察。当被观察的对象更改时,它会通知已注册的观察者,这些观察者收到通知后所执行的操作与被观察者的对象无关。这种模式使得对象可以互相对话,而不必了解原因。

添加和删除观察者的主动权在被观察者一方。

观察者模式在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

   

 

四个角色

1)抽象被观察者角色:一个抽象主题,把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供接口方法,可以增加、删除、通知观察者角色。一般用一个抽象类或者接口来实现。

2)抽象观察者角色:为所有的具体观察者定义一个接口方法,在得到主题通知是更新自己,相当于一个set方法。

3)具体被观察者角色:具体的主题,将有关状态存入具体观察者对象,当具体主题的内部状态改变时,所有登记注册的观察者发出通知。

4)具体观察者角色:具体观察者,实现了抽象观察者中的更新方法,从而使自身的状态与主题的状态相协调。

 

第一个场景例子:有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。

角色:被观察者接口

 1 package com.test.observer;
 2 
 3 public interface Observarable {
 4     /*
 5     被观察者接口
 6     声明了添加、删除、通知观察者的方法
 7      */
 8     public abstract void addObserver(Observer obs);
 9     public abstract void removeObserver(Observer obs);
10     public abstract void notifyObserver();
11 }

 角色:观察者接口

1 package com.test.observer;
2 
3 public interface Observer {
4     /*
5     观察者接口
6     声明了一个方法,当被观察者调用notifyObserver()方法时,观察者的update()方法会被回调。
7      */
8     public abstract void update(String message);
9 }

 角色:实现被观察者接口的具体被观察者类

 1 package com.test.observer;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class WechatServer implements Observarable {
 7     /*
 8     定义被观察者,实现了Observerable接口,对Observerable接口的三个方法进行了具体实现,
 9     同时有一个List集合,用以保存注册的观察者,等需要通知观察者时,遍历该集合即可。
10      */
11     private List<Observer> list;
12     private String message;
13     public WechatServer(){
14         this.list = new ArrayList<Observer>();
15     }
16     @Override
17     public void addObserver(Observer obs) {
18         this.list.add(obs);
19     }
20 
21     @Override
22     public void removeObserver(Observer obs) {
23         if (!this.list.isEmpty()) {
24             this.list.remove(obs);
25         }
26     }
27 
28     @Override
29     public void notifyObserver() {
30         for (Observer aList : list) {
31             aList.update(message);
32         }
33     }
34 
35     public void setInfromation(String str){
36         this.message = str;
37         System.out.println("微信服务更新信息素: " + str);
38         notifyObserver();
39     }
40 }

 角色:实现观察者接口的观察者类

 1 package com.test.observer;
 2 
 3 public class User implements Observer {
 4     /*
 5     观察者,实现了update()方法
 6      */
 7     private String name;
 8     private String message;
 9 
10     public User(String name){
11         this.name = name;
12     }
13     @Override
14     public void update(String message) {  // 功能类似于set方法
15         this.message = message;
16         read();
17     }
18 
19     public void read(){
20         System.out.println(this.name + "收到推送的消息: " + this.message);
21     }
22 }

 测试

 1 package com.test.observer;
 2 
 3 public class TestObserver {
 4     public static void main(String[] args){
 5         WechatServer ws = new WechatServer();
 6         Observer userZhang = new User("Zhang");
 7         Observer userLi = new User("Li");
 8         Observer userZhao = new User("Zhao");
 9         ws.addObserver(userZhang);
10         ws.addObserver(userLi);
11         ws.addObserver(userZhao);
12         ws.setInfromation("Java是世界上最好的语言");
13         System.out.println("----------------------------");
14         ws.removeObserver(userZhang);
15         ws.setInfromation("C语言是世界最好的语言");
16     }
17 }

测试结果

 

第二个场景例子:天气预报

角色:被观察者接口

1 package coding.com.test.observer2;
2 
3 public interface Subject {
4     public abstract void addObserver(Observer obs);
5     public abstract void removeObserver(Observer obs);
6     public abstract void notifyObserver();
7 }

角色:观察者接口

1 package coding.com.test.observer2;
2 
3 public interface Observer {
4     public abstract void update(float temp);
5 }

角色:具体被观察者

 1 package coding.com.test.observer2;
 2 
 3 import java.util.List;
 4 import java.util.ArrayList;
 5 
 6 public class WeatherServer implements Subject {
 7     private List<Observer> list = new ArrayList<>();
 8     private float temp;
 9 
10     @Override
11     public void addObserver(Observer obs) {
12         list.add(obs);
13     }
14 
15     @Override
16     public void removeObserver(Observer obs) {
17         if (!list.isEmpty()){
18             list.remove(obs);
19         }
20     }
21 
22     @Override
23     public void notifyObserver() {
24         for (Observer aList : list){
25             aList.update(temp);
26         }
27     }
28     public void setTemp(float temp){
29         this.temp = temp;
30         notifyObserver();
31     }
32 }

角色:具体观察者1

 1 package coding.com.test.observer2;
 2 
 3 public class WeatherDisplay1 implements Observer {
 4     private float temp;
 5     @Override
 6     public void update(float temp) {
 7         this.temp = temp;
 8         showWeather();
 9     }
10     public void showWeather(){
11         System.out.println("display1: " + temp);
12     }
13 }

角色:具体观察者2

 1 package coding.com.test.observer2;
 2 
 3 public class WeatherDisplay2 implements Observer {
 4     private float temp;
 5     @Override
 6     public void update(float temp) {
 7         this.temp = temp;
 8         showWeather();
 9     }
10 
11     public void showWeather(){
12         System.out.println("Display2; " + temp);
13     }
14 }

测试

 1 package coding.com.test.observer2;
 2 
 3 public class TestObserver {
 4     public static void main(String[] args){
 5         WeatherServer ws = new WeatherServer();
 6         WeatherDisplay1 wd1 = new WeatherDisplay1();
 7         WeatherDisplay2 wd2 = new WeatherDisplay2();
 8         ws.addObserver(wd1);
 9         ws.addObserver(wd2);
10         ws.setTemp(12.57f);
11     }
12 }

测试结果

 

posted on 2018-09-02 23:00  0820LL  阅读(148)  评论(0编辑  收藏  举报

导航