观察者模式是实现代码解耦的一种方式,它包含目标对象和观察者两个元素,当目标对象发生变化是,目标对象将自己的变化推送给所有的观察者,各个观察者根据目标对象的变化,作出响应的处理和判断。实现观察者模式有一点要注意目标对象不能主动取调用观察者,这样才能达到目标对象和观察者的解耦。
观察者模式是建立的一对多的依赖关系。目标和观察者建立的是抽象依赖,具体的目标对象和具体的观察者没有任何依赖关系。
举一个现实中的例子:有一个棵树枝上用绳子挂着一只咸鱼,树下有一只猫和一只狗,它们都眼巴巴的盯着这只咸鱼,都希望能吃到这只咸鱼,所以就他两个一直守望着,用绳子系着的咸鱼就是目标对象,猫和狗就是观察者,用绳子系着的咸鱼和 猫 或者狗之间没有任何的直接的联系。但是,突然有一天 绳子断了,咸鱼掉下来了 (目标对象发生变化了) 这个消息被猫和狗收到了,猫和狗跑过来开始吃咸鱼了。
上述例子的代码实现如下:
目标抽象类维护观察者列表,并负责通知所有的观察者:
package com.designpattern;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
/**
*目标抽象类
*/
public abstract class Subject {
protected List<Observe> observes = new ArrayList<Observe>();
/**
* 增加目标的观察者
* @param observe
*/
public void addObserve(Observe observe){
observes.add(observe);
}
public void deleteObserve(Observe observe){
observes.remove(observe);
}
/**
*通知观察者
*/
public void notifyObserve(){
for (Observe observe:observes ) {
observe.eatResponse();
}
}
}
抽象观察者,定义观察者的接口
/**
* 抽象观察者
*/
public interface Observe {
public void eatResponse();
}
具体的观察者:
小猫
package com.designpattern;
/**
* 小猫观察者
*/
public class CatObserve implements Observe{
@Override
public void eatResponse() {
System.out.println("小猫吃鱼了");
}
}
小狗:
package com.designpattern;
/**
* 小狗观察者
*/
public class DogObserve implements Observe{
@Override
public void eatResponse() {
System.out.println("小狗吃鱼了");
}
}
具体目标实现类:处理自己的业务逻辑,并在需要的时候将消息同步给观察者
package com.designpattern;
import java.sql.SQLOutput;
public class ConcreteSubject extends Subject{
public ConcreteSubject(){
System.out.println("这里是一个绳子系着一只咸鱼");
}
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observe cat = new CatObserve();
subject.addObserve(cat);
Observe dog = new DogObserve();
subject.addObserve(dog);
subject.doSomeThing();
}
public void doSomeThing(){
System.out.println("哎呀 妈呀 绳子断了");
//通知所有的观察者
super.notifyObserve();
}
}
观察者的UML类图: