当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
使用场景:
1、有多个子类共有的方法,且逻辑相同。
2、重要的、复杂的方法,可以考虑作为模板方法。
注意事项:
1、JAVA 中已经有了对观察者模式的支持类。
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
实现
实现如下
观察一个类3个属性变化
- 创建被观察类
public class Subject{
private List<Observer> observers = new ArrayList<>();
private String name;
private String msg;
private int level;
public Subject(String name, int level, String msg) {
this.name = name;
this.level = level;
this.msg = msg;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
notifyAllObservers("l");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyAllObservers("n");
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
notifyAllObservers("m");
}
private void notifyAllObservers(String str) {
for (Observer observer : observers) {
observer.update(str);
}
}
public void attach(Observer observer){
observers.add(observer);
}
}
- 创建观察者抽象类
public abstract class Observer{
protected Subject mSubject;
public abstract void update(String str);
}
- 实现观察者抽象类
public class NameObserver extends Observer{
public NameObserver(Subject subject) {
mSubject = subject;
mSubject.attach(this);
}
@Override
public void update(String str) {
if (str.equals("n")){
System.out.println("Name Change :" + mSubject.getName());
}
}
}
public class MsgObserver extends Observer{
public MsgObserver(Subject subject) {
mSubject = subject;
mSubject.attach(this);
}
@Override
public void update(String str) {
if (str.equals("m")){
System.out.println("Msg Change :" + mSubject.getMsg());
}
}
}
public class LevelObserver extends Observer{
public LevelObserver(Subject subject) {
mSubject = subject;
mSubject.attach(this);
}
@Override
public void update(String str) {
if (str.equals("l")){
System.out.println("Level Change :" + mSubject.getLevel());
}
}
}
- 使用
public void main(String... args){
Subject subject = new Subject("张三",100,"路人甲");
new NameObserver(subject);
new MsgObserver(subject);
new LevelObserver(subject);
subject.setName("李四");
subject.setMsg("主角");
subject.setLevel(1);
}
- 结果
I/System.out: Name Change :李四
I/System.out: Msg Change :主角
I/System.out: Level Change :1