一、介绍
观察者模式是设计模式中行为模式的一种。当对象间存在一对多的依赖关系时,被依赖的对象发生了变化,要求依赖它的所有对象都要做出相应的变化或动作,那么被依赖的对象就是被观察者(主题对象),依赖这个对象的其它对象被称为观察者。
优点: 降低了目标与观察者之间的耦合关系
缺点: 当观察者很多时,通知的发布就会花费很多时间,影响程序效率
角色:
- 抽象目标: 它提供了一个用于保存观察者对象的集合类和增加、删除观察者的方法以及通知所有观察者的抽象方法
- 具体目标: 它实现了通知观察者的方法,当内部状态发生改变时,将通知所有注册了的观察者
- 抽象观察者: 它包含了一个更新自己的方法,当目标状态发生改变时,将会被调用
- 具体观察者: 实现了抽象观察者中的抽象方法
应用: 微信公众号和微信用户、天气预报、JDK的Observer接口
二、设计实现
需求分析与系统设计
场景: 爸爸妈妈照顾宝宝,在宝宝心情发生了变化时,爸爸妈妈要做出相应的回应。
类图如下:
从上面类图中可以看出所有的角色被分为两大类,主题(宝宝)和观察者(爸爸妈妈)
主题(宝宝)的角色里会维护一个观察者(爸爸妈妈)集合,当心情变化时通知观察者里集合里的所有人。抽象出来接口就需要有三个方法,分别是向集合里添加观察者、移除观察者集合里的观察者、通知所有观察者。
观察者(爸爸妈妈)的角色需要有一个接收通知的方法,这个方法就可以抽象出来一个观察者接口。
三、代码实现
被观察者(主题、发布者)
/**
* @ClassName: Subject 主题(发布者,被观察者)
* @Author: whc
* @Date: 2021/04/16/23:32
*/
public interface Subject {
/**
* 注册观察者
* @param observer
*/
void registerObserver(Observer observer);
/**
* 移除观察者
* @param observer
*/
void removeObserver(Observer observer);
/**
* 通知观察者
*/
void notifyObserver();
}
观察者(被通知对象)
/**
* @ClassName: Observer 观察者(被通知对象)
* @Author: whc
* @Date: 2021/04/16/23:33
*/
public interface Observer {
/**
* 接收通知
*/
void update();
}
宝宝
/**
* @ClassName: Baby 宝宝
* @Author: whc
* @Date: 2021/04/16/23:36
*/
public class Baby implements Subject {
private String mood; // 心情
/**
* 宝宝心情改变
* @param mood
*/
public void changeMod(String mood) {
this.mood = mood;
notifyObserver();
}
public String getMood() {
return mood;
}
/**
* 观察者列表
*/
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
for (Observer observer : observers) {
if(null != observer) {
observer.update();
}
}
}
}
爸爸
/**
* @ClassName: Father
* @Author: whc
* @Date: 2021/04/16/23:50
*/
public class Father implements Observer {
private Baby baby;
public Father(Baby baby){
this.baby = baby;
baby.registerObserver(this);
}
@Override
public void update() {
talk();
}
/**
* 说话
*/
private void talk() {
System.out.println("爸爸知道了宝宝的心情:" + baby.getMood());
System.out.println("爸爸说: 宝宝心情变成" + baby.getMood());
}
}
妈妈
/**
* @ClassName: Mother
* @Author: whc
* @Date: 2021/04/16/23:52
*/
public class Mother implements Observer {
private Baby baby;
public Mother(Baby baby) {
this.baby = baby;
baby.registerObserver(this);
}
@Override
public void update() {
action();
}
private void action() {
System.out.println("妈妈知道了宝宝的心情:" + baby.getMood());
System.out.println("妈妈抱起了宝宝");
}
}
测试
/**
* @ClassName: Test
* @Author: whc
* @Date: 2021/04/16/23:56
*/
public class Test {
public static void main(String[] args) {
Baby baby = new Baby();
Father father = new Father(baby);
Mother mother = new Mother(baby);
baby.changeMod("高兴");
baby.changeMod("哭闹");
}
}