1. 观察者模式定义
观察者模式定义了对象之间的一对多依赖,这样以来,当一个对象改变状态时,他的所有观察者都会收到通知并且自动更新。
2. 类图
- 主题接口,对象使用主题接口注册为观察者
- 具体主题必须实现主题接口,除了注册和删除方法外,具体主题还实现了notifyObservers()方法,此方法用于在状态改变时更新所有当前观察者。具体主题也可以有设置和获取状态的方法
- 每个主题可以有许多观察者
- 所有潜在的观察者必须实现观察者接口,这个接口只有update()方法,当主题状态被改变时它会被调用
- 具体观察者可以是实现此接口的任意类。观察者必须注册具体主题,以便接收更新
3.Java实现
3.1 定义主题Interface
package Observer;
/**
* 主题接口:点击
*/
public interface Clickable {
//单击(通知所有观察者)
void click();
//添加单击事件的观察者
void addClickableObserver(ClickableObserver observer);
//移除单击事件的观察者
void removeClickableObserver(ClickableObserver observer);
}
3.2 定义观察者Interface
package Observer;
/**
* 观察者接口
*/
public interface ClickableObserver {//接口
//发生单击事件时的操作
void clicked(Clickable clickable);
}
3.3 定义具体主题
package Observer;
import java.util.ArrayList;
import java.util.List;
/**
* 具体主题,实现主题接口
*/
public class Button implements Clickable{
//存储注册过的单击事件观察者
List<ClickableObserver> observers=new ArrayList<ClickableObserver>();
//按钮信息
String color;//颜色
int x,y;//坐标
@Override
public void click() {
System.out.println("按钮被点击,通知所有观察者");
//执行所有观察者的事件处理方法
for(int i=observers.size()-1;i>=0;i--)
{
observers.get(i).clicked(this);
}
}
@Override
public void addClickableObserver(ClickableObserver observer) {
observers.add(observer);
}
@Override
public void removeClickableObserver(ClickableObserver observer) {
observers.remove(observer);
}
public String toString() {
return "按钮颜色:"+color+",坐标"+x+","+y;
}
}
3.4 定义具体观察者
观察者1
package Observer;
/**
* 具体观察者:改变颜色观察者
*/
public class ChangeColorObserver implements ClickableObserver{
@Override
public void clicked(Clickable clickable) {
Button b=(Button)clickable;
b.color="紫色";
System.out.println("具体观察者(ChangeColorObserver):我收到了主题更新的通知,将主题Button颜色做了改变");
}
}
观察者2
package Observer;
/**
* 具体观察者-改变坐标的观察者
*/
public class ChangeCoordinateObserver implements ClickableObserver{
@Override
public void clicked(Clickable clickable) {
Button b=(Button)clickable;
b.x=100;
b.y=90;
System.out.println("具体观察者(ChangeCoordinateObserver):我收到了主题更新的通知,将主题的坐标做了改变");
}
}
观察者3
package Observer;
/**
* 其他观察者
*/
public class OtherObserver implements ClickableObserver{
@Override
public void clicked(Clickable clickable) {
System.out.println("具体观察者(OtherObserver):我收到了主题更新的通知");
}
}
3.5 定义测试主方法
package Observer;
public class TestMain {
public static void main(String[] args) {//观察者的主程序
Button button = new Button(); // 定义主题对象
button.color="红色"; // 设置主题属性
button.x=0; // 设置主题属性
button.y=0; // 设置主题属性
System.out.println(button);
// 添加多个观察者,用以观察主题
button.addClickableObserver(new ChangeColorObserver());
button.addClickableObserver(new ChangeCoordinateObserver());
button.addClickableObserver(new OtherObserver());
// 主题被"点击",通知所有观察者
button.click();
// 打印主题信息
System.out.println(button);
}
}
输出信息如下:
参考文献:《Head First设计模式(中文版)》弗里曼