java中的观察者模式,在官方API java.util.Observable包中已经存在了。所谓观察者模式,就是一对多的关系。就好比订报,快递等,拿快递来说吧(这里,我们把整个快递流程当成一个快递员)。当我们在网上买了一件商品之后,我们就在家等快递员送货上门,而它是怎样送货的,怎样处理我的订单的,我都不管,他有他的方法,当有新的客户下单时,他以让用同样的程序,只是快递员变了。在这里,快递员就是主题Subject,而客户就是观察者Observer,当观察者在网上下单的时候,就是注册到了主题中。在快递从下单到收到商品的整个过程中,快递员会通知你商品现在的位置。对于同一个商家来说,所有本店的客户都是观察者,卖家就是主题。
在设计观察者模式的时候,为了解耦和,要把对象之间的联系尽量减小,当观察者增多,而代码不能改变。所以用注册的方式比较好,当增加一个观察者就注册进主题中。当一个观察者退出主题的时候,主题就直接删除他,不需要修改其他部分。所以,针对以上总结,用集合作为观察者的容器比较合理。下面就是一段测试代码。
//创建观察者接口,当增加一个观察者就实现该接口,定义好所有对应的观察者的标准。
public interface Observer {
public void update(String msg);
public void show();
public String getName();
}
//创建主题接口,主题需要实现该接口
public interface Subject {
//注册观察者
public void addObserver(Observer observer);
//删除观察者
public void delObserver(Observer observer);
//让所有观察者进行更新数据
public void notifyAllObserver();
}
//主题类
public class SubjectImpl implements Subject {
public ArrayList<Observer> list;
public SubjectImpl(){
list = new ArrayList<Observer>();
}
@Override
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
public void delObserver(Observer observer) {
list.remove(observer);
}
@Override
public void notifyAllObserver() {
for(int i=0;i<list.size();i++){
list.get(i).update(i+" notify ");
}
}
}
//创建观察者类
public class ObserverImpl implements Observer {
private String msg;
//这里为每个观察者定义一个name属性,就像快递单上的电话号码
private String name;
public ObserverImpl(String name){
this.name = name;
}
@Override
public void update(String msg) {
this.msg = msg;
//数据更新之后,就打印
show();
}
@Override
public void show() {
System.out.println(msg);
}
@Override
public String getName(){
System.out.println(name);
return name;
}
}
观察者和主题已经创建完毕,下面来测试。
public class Test {
public static void main(String[] args) {
Subject sub = new SubjectImpl();
Observer o1 = new ObserverImpl("name1");
Observer o2 = new ObserverImpl("name2");
sub.addObserver(o1);
sub.addObserver(o2);
sub.notifyAllObserver();
for(Observer o : sub.list){
o.getName();
}
}
}
//打印结果
0 notify
1 notify
name1
name2
总结:观察者模式的优点又在于,处理了一对多关系的同时,代码量不多,并且随着对象增加,原来的代码不需要改变。