【观察者模式】深入浅出-设计模式 之 观察者模式

0x01.简述

  • 观察者模式(Observer Pattern)(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。(百度百科)
  • 当对象间存在一对多关系时,可以使用观察者模式。
  • 例如,当一个对象被修改时,则会自动通知它的依赖对象。
  • 观察者模式属于行为型模式

0x02.理解观察者模式

一个最为经典的例子:老师与同学的例子。

场景:

一个班的老师有10个学生,老师知道这10个学生的所有信息,老师讲课,学生都能听到,老师点名,对应的同学能起来回答问题。

把这一场景简单化:

  • 其实就是满足了这样的关系:

    • 老师拥有学生们的信息。
    • 学生可以听到老师讲课和点名。

这个例子中的观察者模式:

  • 老师与学生们是一对多的关系。
  • 当老师讲课或者点名时,同学们能做出响应(当一个对象被修改时,则会自动通知它的依赖对象。
  • 在这个例子中,同学们就是观察者,老师就是被观察者。观察者观察被观察者的行为,并通过这些行为做出响应。
    具体的关系可以参考下图:

在这里插入图片描述

  • 将其抽象化,就是如下关系:

在这里插入图片描述

0x03.上述例子的实际代码实现

用代码将这一关系表示出来更容易理解!

  • 总结一下上面的关系,明白我们代码需要做哪些事情:

    • (1)一个老师有10名学生。
    • (2)老师拥有学生的信息。
    • (3)老师点名,学生答到。
  • 接下来具体实现一下:

Person类:(父类)

  • 包含老师和学生的公共属性。
public class Person {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

Student类:

  • 有答到的方法。
public class Student extends Person {

    public void daDao(){
        System.out.println(super.getName()+":到!");
    }

}

Teacher类:

  • 包含学生的信息。
  • 包含一个点到的方法。
public class Teacher extends Person{
    //老师保留学生的信息
    private List<Student> students = new ArrayList<Student>();

    public void Dao() throws InterruptedException {
        while(true){
            int radom = (int)(Math.random()*10);
            Student stu=students.get(radom);
            System.out.println(stu.getName()+" 到了吗?");
            stu.daDao();
            Thread.sleep(3000);
        }
    }
    public void addStu(Student stu){
        this.students.add(stu);
    }
}

Test:

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Teacher teacher=new Teacher();
        teacher.setName("王老师");
        teacher.setAge(27);
        for(int i=0;i<10;i++){
            Student stu=new Student();
            stu.setName("同学"+(i+1));
            stu.setAge(18);
            teacher.addStu(stu);
        }
        teacher.Dao();
    }
}

效果展示:

在这里插入图片描述

0x04.回顾代码–再反思

从我们的代码中可以看出,实现这个小功能的核心代码是:

  • 在Teacher类中存储了所有的Student的信息,这样,只要老师点到,就能调用学生的签到方法。

其实整个观察者模式中,最为重要的就是:当一个对象被修改时,则会自动通知它的依赖对象。

0x05.清楚优势

观察者模式主要用于一对多的关系,它在实际应用中的优势有:

  • (1)降低了目标与观察者之间的耦合关系,将本来的耦合关系变成了抽象耦合关系。
  • (2)目标与观察者之间建立了一套触发机制。

0x06.明白劣势

  • (1)目标与观察者之间的依赖关系并没有完全解除,并且有可能出现循环引用。
  • (2)当观察者直接或间接对象很多时,通知的发布会花费很多时间,影响程序执行的效率。
  • (3)观察者模式仅仅只是知道观察目标发生了变化,无法让观察者知道所观察的目标对象是怎么发生变化的。

0x07.主要应用

Spring MVC的核心处理机制:

  • 在Spring MVC的处理机制中,其实就使用到了观察者模式:
  • 核心控制器就是被观察者,其余的对象就是观察者,当核心控制器发生改变(比如得到Handler),相应的对象就会收到通知,也做出相应的改变。
    在这里插入图片描述

感谢@Mr.ml大佬的指导

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值