以上是API手册里观察者的UML图,(本文主要讨论自己实现观察者模式,JDK内置的就自己百度下吧)从上图中我们可以看出一共需要两个接口,两个具体的实现类,分别是观察者接口,观察者实现类,被观察者接口,被观察者实现类,并且被观察者中会有多个观察者,因此我们想到的是用一个集合框架来储存观察者(例如List),也就是使用组合啦。

下面的东西通过具体代码来解析给大家听。
场景是有一条变色龙,然后有一堆人在猥琐地注视着它(好可怜哇。。。),当变色龙变色的时候,所有人要将新的颜色记录下来。

首先是观察者接口

package org.black.observer;
public interface Observer {
 
public void update(Object observable);
}
代码很简单,update方法做的就是当变色龙变色的时候调用的方法,并且因为要知道变色龙的颜色,所以需要传递一个参数,读者会问,那直接传递String color就可以了哇,写成对象的目的是为了防止需求的改变,万一以后变色龙有没有吐舌头都要你记录的时候,你就可以不需要在此方法多加参数了。

接下来是观察者的实现类。
package org.black.observer;
import org.black.observable.Bsl;

public class Person implements Observer {

    
private String name;

    
public Person(String name){
    
this.name = name;
    }


    
public void update(Object observable) {
    Bsl bsl 
= (Bsl)observable;
    System.out.println(name
+"记录了变色龙的颜色为:"+bsl.getColor());
    }


}


这里代码不做多解析,强转的那个地方也是为了应变需求改变,万一以后不仅仅要记录变色龙,还要记录鹦鹉什么的,那接口的代码也就不需要改变了。

然后是被观察者接口

package org.black.observable;
import org.black.observer.Observer;

public interface Observable {

    
public void addObserver(Observer observer);

    
public void removeObserver(Observer observer);

    
public void notifyAllObserver();
}

 

这里前两个方法为的就是添加观察者和除去观察者呗,通知方法就是当状态改变的时候,要告知所有的观察者,这里可能有点懵,看了实现类就很容易懂了。

下面是被观察者实现类

 

package org.black.observable;
import java.util.ArrayList;
import java.util.List;
import org.black.observer.Observer;
public class Bsl implements Observable {

private String color = "绿色";
private List<Observer> observerList = new ArrayList<Observer>();

public void addObserver(Observer observer) {
observerList.add(observer);
}

public void removeObserver(Observer observer) {
observerList.remove(observer);
}


public void notifyAllObserver() {
for(Observer observer : observerList){
   observer.update(
this);
}

   
}

public void changeColor(String color){
this.color = color;
System.out.println(
"变色龙将颜色变为:"+color);
notifyAllObserver();
}


public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

}


在这里,color就是被观察者的状态啦,当这个状态改变的时候就必须告诉所有的观察者,所以changeColor里面需要调用notifyAllObserver
下面是主函数

package org.black.test;
import org.black.observable.Bsl;
import org.black.observer.Observer;
import org.black.observer.Person;
public class TestObserver {
/**
@param args
*/

public static void main(String[] args) {
Bsl bsl 
= new Bsl();

Observer p1 
= new Person("hjq");
Observer p2 
= new Person("zz");

bsl.addObserver(p1);

bsl.addObserver(p2);

bsl.changeColor(
"黄色");

bsl.removeObserver(p2);

bsl.addObserver(
new Observer(){
   
public void update(Object observable) {
    Bsl bsl 
= (Bsl)observable;
    System.out.println(
"无名氏记录了变色龙的颜色为:"+bsl.getColor());
   }

   
}
);

bsl.changeColor(
"红色");

}

}

 

匿名类的写法相信大家一定非常熟悉了,很像SWING里面的addListener,很方便,遗憾的是,不能知道名字,也没办法remove了。

结果是


变色龙将颜色变为:黄色
hjq记录了变色龙的颜色为:黄色
zz记录了变色龙的颜色为:黄色
变色龙将颜色变为:红色
hjq记录了变色龙的颜色为:红色
无名氏记录了变色龙的颜色为:红色

大家多多支持。。以后会推出更多的设计模式的代码,力求简单生动,易于理解。。