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方法的,就可打印出不同的值;

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

”原创,转载请标注“

原文地址:https://www.cnblogs.com/taofudemo/p/4623230.html