1.什么是观察者模式?
定义:在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新.
举个栗子: 张三和李四准备上演一场抢劫银行的行动,张三负责抢劫,李四负责放哨,他们两约定,如果李四这边看到警察来就立即通知张三,张三收到通知后立马逃跑…在上面的例子中,张三的角色其实就是观察者,李四是被观察者.张三观察李四这边的状态,如果李四这边的状态发生改变(一切正常->情况不妙),张三就立即做出行动或反馈.现实中类似的还有消息的订阅和接收,比如微信公众号,其模式其实也是观察者模式.
2.为什么要使用观察者模式?
观察者模式可以降低系统耦合度,观察者和主体(被观察者)完美分离,另外主体的变化可以通知到所有匹配过的观察者,所有依赖于主体的对象都得到通知并自动刷新。
3.实现
先来看一下观察者模式的结构图:
观察者模式主要由观察者(Observer),主体(Subject)构成,再具体一点就是由抽象观察者(observer),抽象主体(subject),观察者实现类(concreteObserver),主体实现类(concreteSuject)构成,为了让代码具有更高的可扩展性,你还可以把主体写成抽象类,我这了为了演示就不写的太复杂了,感兴趣的可以看看百度百科提供的观察者模式-javaDemo,那段代码写的很精彩,值得一读.
Subject:
主体,存放所有观察者对象,存放自身状态,以及添加/移除观察者的方法,通知所有观察者的方法
/**
* 被观察者对象
*/
public class Subject {
private List<Observer> observers = new ArrayList<>();
private Integer state;
public void attach(Observer observer) {
observers.add(observer);
}
public void remove(Observer observer) {
observers.remove(observer);
}
private void notifyALLObserver() {
for (Observer observer : observers) {
observer.update();
}
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
this.notifyALLObserver();
}
}
observer:
观察者对象,提供了update方法,以供在收到通知时及时作出反应.
/**
* 观察者对象
*/
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
下面我以一个具体的例子来模拟实现观察者模式. 现在有一对情侣,主体是丈母娘,只有在丈母娘状态发生改变时(???)情侣才能作出具体的反馈,比如丈母娘的状态由1变为了2(可以理解为生气变成了高兴),这个时候男生看到后会立刻去打游戏,女生看到后则会去购物,代码模拟实现一下:
public class BoyObserver extends Observer {
/**
* 被构造时即被添加至观察者列表里
*/
public BoyObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("状态改变了,状态值变为了:" + subject.getState() + " 我要去打游戏了....");
}
}
public class GirlObserver extends Observer {
/**
* 被构造时即被添加至观察者列表里
*/
public GirlObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("状态改变了,状态值变为了:" + subject.getState() +" 我要去购物了....");
}
}
/**
* 测试客户端
*/
public class Client {
public static void main(String[] args) {
Subject subject = new Subject();
Observer girlObserver = new GirlObserver(subject);
Observer boyObserver = new BoyObserver(subject);
System.out.println("==========第一次===========>");
subject.setState(1);
System.out.println("==========第二次===========>");
subject.setState(2);
System.out.println("==========第三次===========>");
subject.remove(boyObserver);
subject.setState(3);
}
}
运行一下测试类可以看到控制台输出:
第一次当主体状态变为1时,男孩和女孩都收到了通知,于是两人都去干自己喜欢的事了,第二次也一样,第三次时,丈母娘不高兴让男孩打游戏了,觉得这样没出息,于是把他从列表里踢出去了,然后他就收不到通知了…
以上便是观察者模式的简单实现,如果想要提高代码的可扩展性,可以把主体写得更抽象,运用泛型和反射,让代码的扩展性爆棚.