我们不管是在开发中,还是在面试的过程中,或多或少的都会接触到观察者模式,其实程序中的观察者模式都是来源于生活,
比如猫捉老鼠,观察者就是猫,被观察者就是老鼠,而事件触发就是声响或者气味,或者老鼠偷吃食物等等,当老鼠(被观察者)做出某些动作时就会被猫(观察者)所监听到;
再如微信端的消息订阅,公众号(被观察者),关注公众号的人(观察者),公众号更新消息后就会被观察者观测到。
类比到代码中:
1.1、被观察者
/**
* 被观察者,用于添加 删除 通知 观察者
*/
public interface Observered {
//添加一个观察者
void addObservers(Observer ob);
//移除一个观察者
void removeObservers(Observer ob);
//通知观察者
void notifyObservers();
}
1.2、 接口实现
/**
* 具体被观察者类型
*/
public class CarObservered implements Observered {
private List<Observer> observsers;
private String message;
public CarObservered() {
observsers = new ArrayList<>();
}
@Override
public void addObservers(Observer ob) {
observsers.add(ob);
}
@Override
public void removeObservers(Observer ob) {
if (!observsers.isEmpty())
observsers.remove(ob);
}
@Override
public void notifyObservers() {
if (!observsers.isEmpty()) {
for (Observer observer : observsers) {
observer.refresh(this.message);
}
}
}
private void setInfomation(String message){
this.message = message;
System.out.println("当前消息为"+this.message);
notifyObservers();
}
2.1、观察者
/**
* 抽象观察者,当被观察者被执行notifyObservers时,回调refresh
*/
public interface Observer {
/**
* 用于回调通知消息
* @param message
*/
void refresh(String message);
}
2.2、观察者实现
/**
* 具体观察者类型
*/
public class CarObserver implements Observer{
private String name;
private String message;
public CarObserver(String name){
this.name = name;
}
@Override
public void refresh(String message) {
this.message = message;
printInfomation();
}
private void printInfomation(){
System.out.println(name+"你好,当前关注了"+message);
}
}
3、简单测试
public static void main(String[] args) {
Observered observered = new CarObservered();
CarObserver car1 = new CarObserver("zs");
CarObserver car2 = new CarObserver("ls");
CarObserver car3 = new CarObserver("zw");
observered.addObservers(car1);
observered.addObservers(car2);
observered.addObservers(car3);
((CarObservered) observered).setInfomation("FM97.7");
System.out.println("华丽的分隔符----------------------------------------------------------------");
observered.removeObservers(car1);//张三退出观察
((CarObservered) observered).setInfomation("FM97.8");
}
4、打印结果
com.gg.Test
当前消息为FM97.7
zs你好,当前关注了FM97.7
ls你好,当前关注了FM97.7
zw你好,当前关注了FM97.7
华丽的分隔符----------------------------------------------------------------
当前消息为FM97.8
ls你好,当前关注了FM97.8
zw你好,当前关注了FM97.8
Process finished with exit code 0
5、总结,具体的项目中的观察者模式会复杂的多,会涉及到多个不同的观察者,不同观察者所做出的动作也不尽相同,会根据实际的业务需求实现其业务需要的逻辑,这也是为什么需要抽象接口,面向接口编程,毕竟需要遵循java六大设计原则之一的依赖倒置原则。有错请老鸟指出,不胜感激。