「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
行为型模式,就是描述对象之间的交互关系和交互方法
概述
什么叫做观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
什么时候使用观察者模式
当对象间存在一对多的关系,当前对象的修改需要通知到其他各个依赖它的对象时使用,广播通知。
例子
用菜鸟教程中的一个例子说明非常精确:“拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。”这个拍卖师就是一个观察者
其实我们平时使用MQ,也贯彻这种思想。就是一个数值的改变会通知依赖于这个数值的各个程序
实现
逻辑实现
父母的户口薄中的姓名更换,子女的户口薄“父亲”一列信息也会更换
- 创建父亲类(parent),其中属性为name、childrens、notifyAllObservers()发放进行通知子女信息。
- 创建观察者,观察者中有parent ,abstract void update();parentName方法
- 实现子女信息,其中update方法实现观察更新逻辑
代码实现
- 实现父亲类,注意,修改姓名之后需要通知到它所有的依赖者
public class Parent {
/**
* 受其他类所依赖的点
*/
private List<Children> childrens
= new ArrayList<Children>();
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyAllObservers();
}
public void attach(Children children){
childrens.add(children);
}
public void notifyAllObservers(){
for (Children children : childrens) {
children.update();
}
}
}
复制代码
- 实现孩子的抽象方法及孩子
public abstract class Children {
protected Parent parent;
public abstract void update();
}
public class Daughter extends Children {
/**
* 监控参数
*/
private String parentName;
public Daughter(Parent parent) {
//实现该对象时候,将该对象依赖到Parent的对象中
this.parent = parent;
this.parent.attach(this);
}
@Override
public void update() {
//处理观察变化的逻辑
this.parentName = parent.getName();
System.out.println("i'm daughter ,my Father name is : "
+ parent.getName());
}
}
public class Son extends Children {
/**
* 监控参数
*/
private String parentName;
public Son(Parent parent) {
//实现该对象时候,将该对象依赖到Parent的对象中
this.parent = parent;
this.parent.attach(this);
}
@Override
public void update() {
//处理观察变化的逻辑
this.parentName = parent.getName();
System.out.println(" i'm son ,my Father name is : "
+ parent.getName());
}
}
复制代码
- 测试实现。
public class ObServerDemo {
public static void main(String[] args) {
Parent parent = new Parent();
new Son(parent);
new Daughter(parent);
parent.setName("李刚");
parent.setName("王刚");
}
}
输出:
i'm son ,my Father name is : 李刚
i'm daughter ,my Father name is : 李刚
i'm son ,my Father name is : 王刚
i'm daughter ,my Father name is : 王刚
复制代码
由此可见那个循环通知的操作,如果依赖者过多,会导致进行相关通知的逻辑太多。所以其实这块逻辑可以再优化下,将找个通知的过程异步出去,开一个单独的线程进行处理(又设计数据同步和锁的问题了)。