观察者模式定义了对象之间的一对多的依赖关系,当一个对象(被观察者)改变状态时,它的所有依赖者(观察者)都会收到通知并更新
为了交互对象之间的松耦合设计而努力
在这个模式中存在两个角色,一个是 “被观察者”,另一个是 “观察者”,他们之间的关系类似现实生活中的“报刊订阅”,其中被观察者是“报社”,观察者是“用户”,用户在报社购买报刊订阅服务后,报社一旦有新报刊发布,就会通知用户,而如果用户取消订阅,以后报社就不会通知该用户。从报社通知用户到用户得到报刊有两种过程,一种是报社将报刊送到用户家里(push),另一种是用户自己到报社取(pull),其中第一种过程是不管用户是否需要这份报刊,报社都会将最新的报刊送到用户家里,而第二种是用户根据自己的需要,到报社取需要的报刊,这是两种过程的区别。
下面是观察者模式的类图
以下代码模拟一个报刊订阅的过程,有一家叫做 DailyNews 的报社,Tom 和 Jerry 都注册了这家报社的最新消息订阅服务,每当有最新消息到来,报社就会通知他们,接着 Tom 取消了这个服务,则报社的最新消息不会通知 Tom 而只通知 Jerry。在这个过程中,DailyNews 报社扮演被观察者角色,Tom 和 Jerry 两个用户扮演观察者角色
定义了具体用户与具体报社之前的通信接口,通过这个接口,报社可以将通知更新给所有已注册用户
public interface User {
public void update(String content);
}
具体报社需要具有 注册观察者,删除观察者,通知观察者的功能,因此抽象报社定义了这三个通用的方法
public interface NewsPaper {
public void registerUser(User u);
public void removeUser(User u);
public void notifyNews(String content);
}
这是一家叫做 DailyNews 的报社,用户可以在这里注册订阅,也可以取消订阅,报社会将最新消息通知给用户
public class DailyNews implements NewsPaper {
private List userList;
public DailyNews() {
userList = new ArrayList<>();
}
@Override
public void registerUser(User u) {
userList.add(u);
}
@Override
public void removeUser(User u) {
userList.remove(u);
}
@Override
public void notifyNews(String content) {
for (User u:userList){
u.update(content);
}
}
}
Tom 和 Jerry 是两个用户,他们可以订阅报社的最新消息,一旦报社有最新消息,就会通过 update() 方法通知给他们
public class TomUser implements User{
@Override
public void update(String content) {
System.out.println("Tom 收到最新消息: "+content);
}
}
public class JerryUser implements User {
@Override
public void update(String content) {
System.out.println("Jerry 收到最新消息: "+content);
}
}
测试类中模拟上面描述的实例需求
public class MainTest {
public static void main(String[] args) {
DailyNews daily = new DailyNews();
User tom = new TomUser();
User jerry = new JerryUser();
//向报社注册用户
daily.registerUser(tom);
daily.registerUser(jerry);
daily.notifyNews("DailyNews报社今日最新消息");
System.out.println("用户 tom 退订了");
daily.removeUser(tom);
daily.notifyNews("DailyNews报社明日消息");
}
}
运行效果
以上,一个简单的观察者模式的实例就实现了,目前对这个模式的理解还比较粗浅,希望在以后的学习中能够深入理解这种模式
//胡思乱想:观察者模式和回调。。。有点混乱,那Android中的点击事件举例,其实使用观察者模式也是可以实现的吧,界面是被观察者,系统的触摸事件响应是观察者,当用户点击界面,触发被观察者更新,那么系统就能接收到这个更新,然后继续处理了。而回调呢,界面中把按键事件编写好,系统在接收到用户触摸事件时再去吊用这个事件,这样,额,先这样吧