• java中常见的模式之自定义观察者和java库中观察者


    java定义了一种观察者接口对象,用于所有观察者类去实现它。也可以自定义的创建观察者接口,其中的原理都是差不多.

    现在来简述第一种自定义观察者的原理:

    1.首先建立一个观察者接口MyObserver.java,并写上抽象方法(当观察的目标改变了就会执行的更新操作),代码如下:

    /**
     * 
     *这是观察者的抽象类,其他实体的观察者都要去实现它;
     */
    public interface MyObserver { 
    	/**
    	 * 更新
    	 * @param subject
    	 */
    	public void update(MySubject subject);
    }
    

    这里的update方法中传了 要观察的目标对象;

    2.创建一个目标对象,作为所有观察者的目标对象,也是所有目标的父类;其中代码如下:

     1 import java.util.ArrayList;
     2 /**
     3  * 观察者的目标类
     4  * @author Administrator
     5  *
     6  */
     7 public class MySubject {
     8     
     9     public ArrayList<MyObserver> mObservers = new ArrayList<MyObserver>();
    10     
    11     /**
    12      *添加观察者到 列表里,
    13      *代表了所有的观察该目标的观察者
    14      * @param obs
    15      */
    16     public void attach(MyObserver obs){
    17         mObservers.add(obs);
    18     }
    19     /**
    20      * 移除 在观察目标该列表里的观察对象
    21      * @param obs
    22      */
    23     public void datach(MyObserver obs){
    24         mObservers.remove(obs);
    25     }
    26     
    27     /**
    28      * 当目标值改变,就应该调用的方法
    29      * 这个方法是去刷新观察者列表里的每个观察者对象,这样观察者对象就会做出改变
    30      */
    31     public void notifyMyObserver(){
    32         for(int i=0;i<mObservers.size();i++){
    33             MyObserver observer = mObservers.get(i);
    34             observer.update(this);
    35         }
    36     }
    37 }

    就这样,自定义观察者中的基类就写完 了;

    有了这两个基类,我们就可以做点示例的东西来诠释一下观察者模式的用处:

    1.假设 两个对象,一个是学生Student.java ,一个是天气Weather.java  ,学生去观察天气的变化;

     天气作为目标,继承了目标基类,代码如下:

     1 public class Weather extends MySubject {
     2     
     3     //天气的属性
     4     private String info;
     5     private String action;
     6 
     7     public String getInfo() {
     8         return info;
     9     }
    10     /**
    11      * @param info
    12      * @param action
    13      * 当set 来改变目标时。观察者就会得到刷新
    14      */
    15     public void setInfo(String info,String action) {
    16         this.info = info;
    17         this.action = action;
    18         notifyMyObserver();
    19     }
    20     public String getAction() {
    21         return action;
    22     }
    23 
    24     
    25 
    26 }

    解释一下,当天气的通过set方法来改变时,就会执行notifyMyobserver()方法,而观察者就会做出回应;

    2,学生作为观察者来实现MyObserver接口,并实现该功能;代码如下:

     1 /**
     2  * 学生是观察者之一,而学生 观察的目标 是 天气
     3  * 
     4  * @author Administrator
     5  *
     6  */
     7 public class Student implements MyObserver {
     8 
     9     //增加学生的属性
    10     private String name;
    11     private String sex;
    12     private int age;
    13     
    14     public Student(String name,String sex){
    15         this.name = name;
    16         this.sex = sex;
    17     }
    18     /* (non-Javadoc)
    19      * @see MyObserver#update(MySubject)
    20      * 实现方法
    21      */
    22     @Override
    23     public void update(MySubject subject) {
    24         Weather weather = (Weather) subject;//将父类对象强制转换为 子类对象
    25         
    26         //获取到监督的目标对象的信息
    27         String info = weather.getInfo();
    28         String action = weather.getAction();
    29         //打印
    30             if(info.equals("下雨")){
    31                 System.out.println("今天是:"+info+" "+name+"将要去"+action);
    32             }
    33         
    34     }
    35 
    36 }

    这里的关系有些绕,多看看就可以理解到位;

    到这里自定义的观察者模式就演示完了


    那么现在来看看简单的java库中的 观察者模式;

    同样的原理,但是这里就不用去定义接口观测者,和目标基类,而是使用java库的;

    先贴出,Weather.java目标类代码如下:

     1 import java.util.Observable;
     4 public class Weather extends Observable{
     5     private String info;
     6     private String wendu;
     7     public String getInfo() {
     8         return info;
     9     }
    10     public void setInfo(String info,String wendu) {
    11         this.info = info;
    12         this.wendu = wendu;
    13         setChanged();//改变了目标
    14         /*
    15          * 这里有两个方法,分别notifyObservers(),notifyObservers(org)有参数和无参数;有参数的刷新方法,就会传递
    16             对应的参数到  观察者的 update(Observable arg0, Object arg1)中的 org1,而无参的刷新方法中,传入的是整个目标对象arg0
    17         */
    18         notifyObservers();//java中定义的,就是继承了 目标观察者的方法,去刷新观察者
    19         //notifyObservers(wendu);
    20     }
    21     public String getWendu() {
    22         return wendu;
    23     }
    26 }

    那么,student.java观察者类代码:

     1 import java.util.Observable;
     2 import java.util.Observer;
     3 
     4 
     5 /**
     6  * @author Administrator
     7  * 实现java中定义好的 观察者接口,其实现方法和自定义的类似
     8  *
     9  */
    10 public class Student implements Observer {
    11     //增加学生的属性
    12     private String name;
    13     private String sex;
    14     private int age;
    15     
    16     public Student(String name,String sex){
    17         this.name = name;
    18         this.sex = sex;
    19     }
    20     
    21     /* (non-Javadoc)
    22      * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
    23          这里的
    24      */
    25     @Override
    26     public void update(Observable arg0, Object arg1) {
    27         Weather w = (Weather) arg0;
    28         //获取到监督的目标对象的信息
    29         String info = w.getInfo();
    30         String action = w.getWendu();
    31         //打印
    32             if(info.equals("下雨")){
    33                 System.out.println("今天是:"+info+" "+name+"将要去"+action);
    34             }
    35         
    36     }
    37         
    38         
    39 
    40 
    41 }

    在来个测试类代码,

     1 /**
     2  * @author Administrator
     3  *这是个测试类
     4  */
     5 public class main {
     6     public static void main(String args[]) {
     7         
     8         //写观察者的目标对象
     9         Weather w = new Weather();
    10         
    11         //两个学生的观察者
    12         Student st1 = new Student("小剑", "38");
    13         Student st2 = new Student("gooddog", "39");
    14         
    15         //用java中定义好的添加方法来吧目标 添加观察者对象(就是让这些观察者去观察它)
    16         w.addObserver(st2);
    17         w.addObserver(st1);
    18         
    19         //通过set来怪不数据,测试观察者数据是否会随着改变
    20         w.setInfo("下雨", "去网吧");
    21     }
    22 }

    嗯,到这里观察这模式就结束了,通过控制台打印就可以看到,改变了weather set方法的,就可打印出不同的值;

    具体的就个人去测试吧;如果要源码就请留言。

    ”原创,转载请标注“

  • 相关阅读:
    python网络爬虫——scrapy核心组件介绍、请求传参、下载中间件
    python网络爬虫——Scrapy全站数据爬取【手动请求发送】及post请求的发送
    python网络爬虫——scrapy框架持久化存储
    php常见排序
    php实现快速排序
    mysql读写分离 主从同步
    php预定义字符
    本地Navicat连不上Linux虚拟机MySQL数据库问题
    php yii 命令
    yii 定义场景
  • 原文地址:https://www.cnblogs.com/taofudemo/p/4623230.html
Copyright © 2020-2023  润新知