zoukankan      html  css  js  c++  java
  • 设计模式——观察者模式

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

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

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

       

    四个角色

    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 }

    测试结果

  • 相关阅读:
    ARM裸机开发(二)中断编程
    Linux汇编与C互相调用
    Java 2009
    MFC对Socket编程的支持
    Thinkpad
    IE9
    ASP.NET MVC学习教材
    sysprep.exe修改SID
    查询显示进度条
    MOSS2007中型服务场管理 教材<02>: SubSite Backup & Restore
  • 原文地址:https://www.cnblogs.com/0820LL/p/9575897.html
Copyright © 2011-2022 走看看