定义:
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
可以理解为报纸配送员配送报纸,订阅报纸就会每天收到报纸,不订阅就收不到报纸了。
模式结构图:
举个例子:配送员配送报纸
首先定义一个报亭接口:
public interface Newsstand{
//这两个方法都需要一个观察者作为变量,用来注册或者被删除的
void registerObsercer(News n);
void removeObserver(News n);
//当主题状态被改变时,会调用这个方法,通知所有观察者
void notifyObserver();
}
配送员实现接口
public class Courier implements Newsstand {
private List<News> list;
private String message;
public Courier(){
list = new ArrayList<News>();
}
@Override
public void registerObsercer(News n) {
list.add(n);
}
@Override
public void removeObserver(News n) {
if(!list.isEmpty()){
list.remove(n);
}
}
@Override
public void notifyObserver() {
for(int i=0;i<list.size();i++){
News observer = list.get(i);
news.update(message);
}
}
public void setInfomation(String s){
this.message = s;
System.out.println("最新消息:"+s);
notifyObserver();
}
}
定义新闻接口
public interface News {
//需要发送的消息内容
void update(String message);
}
订阅者实现接口
public class User implements News {
private String name;
private String message;
public User(String name){
this.name = name;
}
@Override
public void update(String message) {
this.message = message;
read();
}
public void read(){
System.out.println(name + " 收到推送消息: " + message);
}
}
场景测试
public class Client {
public static void main(String[] args) {
Courier server = new Courier();
//创建人员
News zhangsan = new User("zhangsan");
News lisi = new User("lisi");
News wangwu = new User("wangwu");
//注册多个订阅者
server.registerObsercer(zhangsan);
server.registerObsercer(lisi);
server.registerObsercer(wangwu);
//发布消息
server.setInfomation("程序员不用加班啦!!");
System.out.println("----------------------------------------------");
//张三退出订阅,接收不到消息
server.removeObserver(zhangsan);
//发布消息
server.setInfomation("上一条是谣言!!!");
}
}
输出结果:
总结:
- 这个模式是松偶合的。改变主题或观察者中的一方,另一方不会受到影像。
- JDK中也有自带的观察者模式。但是被观察者是一个类而不是接口,限制了它的复用能力。
- 在JavaBean和Swing中也可以看到观察者模式的影子。
版权声明:本文为weixin_44564365原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。