基本概念:
观察者模式属于行为型模式,其意图是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
这一个模式的关键对象是目标(Subject)和观察者(Observer)。一个目标可以有任意数目的依赖它的观察者,一旦目标的状态发生改变,所有的观察者都得到通知,作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。
适用场景:
观察者模式,用于存在一对多依赖关系的对象间,当被依赖者变化时,通知依赖者全部进行更新。
因此,被依赖者,应该有添加/删除依赖者的方法,且可以将添加的依赖者放到一个容器中;且有一个方法去通知依赖者进行更新。
依赖者更新发布者产生的变化。
大白话:
其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
可类别比 消息队列 ActivityMQ RabbitMQ
思想:
建立目标(subject)与观察者(observer)接口:
目标(subject)接口:
- 建立一个注册观察者对象的接口; public void attach(Observer o);
- 建立一个删除观察者对象的接口; public void detach(Observer o);
- 建立一个当目标状态发生改变时,发布通知给观察者对象的接口; public void notice();
观察者(observer)接口:
- 建立一个当收到目标通知后的更新接口: public void update();
角色:
抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
生活场景:
- 有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。
- 学生需要知道老师的电话号码以便于在合时的时候拨打,老师就是一个被观察者(Subject),学生就是需要知道信息的观察者,当老师的电话号码发生改变时,学生得到通知,并更新相应的电话记录。
- 村长发布广播信息,村民获取信息。
代码实现:
结构图:
村长接口(发布者)subject
/**
* 村长接口
* 目标(subject)接口
*/
public interface VillageHead {
public void addVillager(Villager villager);
public void removeVillager(Villager villager);
public void notifyVillager();
}
村民接口(订阅者)Observer
/**
* 村民接口
* 观察者(observer)接口
*/
public interface Villager {
public void undateMessage(String message);
}
村长实现类
import com.design.observer.VillageHead;
import com.design.observer.Villager;
import java.util.ArrayList;
import java.util.List;
/**
* 村长接口实现类
* 目标(subject)接口实现类
*/
public class VillageHeadImpl implements VillageHead{
private List<Villager> list;
private String message;
public VillageHeadImpl(){
list = new ArrayList<Villager>();
}
@Override
public void addVillager(Villager villager) {
list.add(villager);
}
@Override
public void removeVillager(Villager villager) {
if(!list.isEmpty()){
list.remove(villager);
}
}
@Override
public void notifyVillager() {
for (Villager villager : list) {
villager.undateMessage(message);
}
}
public void setMessageForVillage(String message){
this.message = message;
System.out.println("村长发布信息:" + message);
notifyVillager();
}
}
村民实现类
import com.design.observer.Villager;
/**
* 村民接口实现类
* 观察者(observer)接口实现类
*/
public class VillagerImpl implements Villager{
private String name;
public VillagerImpl(String name){
this.name = name;
}
@Override
public void undateMessage(String message) {
System.out.println(name + " 接收到通知:" + message);
}
}
测试类
import com.design.observer.VillageHead;
import com.design.observer.Villager;
import com.design.observer.impl.VillageHeadImpl;
import com.design.observer.impl.VillagerImpl;
public class Main {
public static void main(String[] args) {
//创建村长
VillageHeadImpl villageHead = new VillageHeadImpl();
//创建村民
Villager rh = new VillagerImpl("如花");
Villager gd = new VillagerImpl("狗蛋");
Villager wdy = new VillagerImpl("王大爷");
//添加订阅者
villageHead.addVillager(rh);
villageHead.addVillager(gd);
villageHead.addVillager(wdy);
//发布信息
villageHead.setMessageForVillage("狗蛋娶了如花 ");
System.out.println("--------------------------");
//取消订阅
villageHead.removeVillager(wdy);
//发布消息
villageHead.setMessageForVillage("王大爷退出寡妇村");
}
}
测试结果: