设计模式——观察者模式

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

行为型模式,就是描述对象之间的交互关系和交互方法

概述

什么叫做观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

什么时候使用观察者模式

当对象间存在一对多的关系,当前对象的修改需要通知到其他各个依赖它的对象时使用,广播通知。

例子

用菜鸟教程中的一个例子说明非常精确:“拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。”这个拍卖师就是一个观察者

其实我们平时使用MQ,也贯彻这种思想。就是一个数值的改变会通知依赖于这个数值的各个程序

实现

逻辑实现

父母的户口薄中的姓名更换,子女的户口薄“父亲”一列信息也会更换

  1. 创建父亲类(parent),其中属性为name、childrens、notifyAllObservers()发放进行通知子女信息。
  2. 创建观察者,观察者中有parent ,abstract void update();parentName方法
  3. 实现子女信息,其中update方法实现观察更新逻辑

代码实现

  1. 实现父亲类,注意,修改姓名之后需要通知到它所有的依赖者
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();
        }
    }
}
复制代码
  1. 实现孩子的抽象方法及孩子
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());
    }
}
复制代码
  1. 测试实现。

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 : 王刚
复制代码

由此可见那个循环通知的操作,如果依赖者过多,会导致进行相关通知的逻辑太多。所以其实这块逻辑可以再优化下,将找个通知的过程异步出去,开一个单独的线程进行处理(又设计数据同步和锁的问题了)。

分类:
后端
  • Reboot
    17小时前