欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Java编程的Observer观察者设计模式

程序员文章站 2024-03-08 19:52:22
 java语言里包含了许多对设计模式的直接支持,如command模式,agent模式,observer模式等。虽然java提供的对这些模式的支持很简单,不能满足比...

 java语言里包含了许多对设计模式的直接支持,如command模式,agent模式,observer模式等。虽然java提供的对这些模式的支持很简单,不能满足比较复杂的应用。但在简单的场景下,使用这些类往往能够得到立杆见影的效果。所以,如果没有什么特殊需求,还是最好利用java的这些类。
        observer模式,又称监听模式,观察者模式,是经典设计模式之一(one of gof)。java语言中,对这种模式支持的类和接口主要有以下几个,全部来自java.beans包:

java.beans.propertychangelistener (interface) 
java.beans.propertychangesupport (class)
java.beans.propertychangeevent (class)
java.beans.propertychangelistener

      这是一个接口,很显然,所有实现这个接口的类就是listener啦(或者叫observer),它会对被监听的对象的某些变化感兴趣。这个接口就一个方法:

public void propertychange(propertychangeevent evt) {  
// todo auto-generated method stub  
} 

接口定义很简单,作用也很明显。接受一个event(被监听者产生的propertychangeevent),然后根据这个event做点反应。

 java.beans.propertychangesupport 

         这个类用在被观察者的类里,用来保存注册的观察者,并负责向他们提供被观察者的变化信息。这个类的方法也不多,不过还是只介绍100%用到的,要不脑子就不够使了,呵呵。

public propertychangesupport(object sourcebean) 

      这是构造函数,参数就是被监听者。propertychangelistener一般作为被监听者的一个属性。一般如下使用:

private propertychangesupport listeners = new propertychangesupport(this); 

 
      注意,这个listeners可不是只代表一个监听者,他可能是一群监听者。那么如何这些listeners是谁呢?这回用到下面的方法了。

public void addpropertychangelistener(propertychangelistener listener) 

        这个类太容易了,把监听者加进来。就像开十七大一样,记者想要采访,就得先登记一下。显然这个方法可以多次调用(add嘛)。有加就有减:

public void removepropertychangelistener(propertychangelistener listener) 

如果这个监听者对被监听者的任何变化多不感兴趣了,就被被监听者赶了出去。
好了,记者都到齐了,被监听者有变化了就该通知人家了,使用如下方法的一个:

public void firepropertychange(propertychangeevent evt)  
 
public void firepropertychange(string propertyname,  
                boolean oldvalue,  
                boolean newvalue)  
 
public void firepropertychange(string propertyname,  
                int oldvalue,  
                int newvalue)  
 
public void firepropertychange(string propertyname,  
                object oldvalue,  
                object newvalue) 

实际上,后三个方法的参数都会封装成propertychangeevent,然后调用第一个方法。不过在实际中,我们还是喜欢直接调用后三个中的一个,封装的事我们就不管了。后三个方法的参数都是三个,其中的oldvalue和newvalue就是改变前后的值,第一个就是给改变一个名字,好让监听者们根据这个名子来做响应。就像开会,*的所有信息都会被记者听到,但是有的记者只对*问题感兴趣,而有的记者对中日问题感兴趣。
对propertychangesupport方法的介绍就这么多吧。注意,propertychangesupport既然被用到了被观察者的类(一般是一个model)里,那么他的这些方法就只在被观察这里调用。

java.beans.propertychangeevent

       这个类我也懒得介绍,看看他的主要方法就明白怎么回事了

public string getpropertyname()  
public object getnewvalue()  
public object getoldvalue() 

就者三个类,再有就是具体问题具体分析了。来个例子吧,首先是被观察者:

public class domain{  
  protected string id;  
  protected string name;  
  protected string desname;  
 
  protected propertychangesupport listeners = new propertychangesupport(this);  
 
  public string getid() {  
    return id;  
  }  
 
  public void setid(string id) {  
    this.id = id;  
    firepropertychange("domain.id", null, id);  
  }  
 
  public string getdesname() {  
    return desname;  
  }  
 
  public void setdesname(string desname) {  
    this.desname = desname;  
    firepropertychange("domain.desname", null, desname);  
  }  
 
  public string getname() {  
    return name;  
  }  
 
  public void setname(string name) {  
    this.name = name;  
    firepropertychange("domain.name", null, name);  
  }  
 
  public void addpropertychangelistener(propertychangelistener listener) {  
    listeners.addpropertychangelistener(listener);  
  }  
 
  public void firepropertychange(string propname, object oldvalue, object newvalue) {  
    listeners.firepropertychange(propname, oldvalue, newvalue);  
  }  
 
  public void removepropertychangelistener(propertychangelistener listener) {  
    listeners.removepropertychangelistener(listener);  
  }  
} 

有人对domain的三个属性感兴趣。下面就是这些人中的一个:

public class simpleobserver implements propertychangelistener {  
    
  ....  
    
  @override 
  public void propertychange(propertychangeevent evt) {  
    if(evt.getpropertyname().equals("domain.name")){  
      //do some work  
    }  
  }  
    
} 

下面是个简单的测试类:

public class simpletest{  
  public static void main(string[] args) {  
    simpleobserver observer = new simpleobserver();  
    domain domain = new domain();  
    domain.addpropertychangelistener(observer);  
    domain.setname("yangsq");  
    ......  
  }  
} 

很显然,可以观察到simpleobserver中propertychange方法的执行。