设计模式(3):观察者模式

一、概念

1、定义:一(主题对象)对多(观察者对象)中,主题对象发生变化时,及时通知观察者进行更新,观察者可以订阅/取消订阅主题对象

2、类型:行为型

3、适用场景:关联行为场景,建立一套链式触发机制(触发链条,A通知B,B通知C)

4、优缺点

优点

  • 观察者与被观察者之间建立了一个抽象的耦合,不管是增加观察者还是被观察者,都很容易扩展
  • 观察者模式支持广播通信

缺点

  • 观察者之间细节依赖太多,增加程序复杂度(比如触发链条)
  • 要避免循环调用,可能导致系统崩溃

5、UML 在这里插入图片描述
观察者模式提供了一种对象设计,让主题和观察者之间低耦合,主题只知道观察者实现了Observer接口,主题不需要知道观察者的具体类是谁(因为所有观察者实现了相同的Obsever接口这是主题知道的,每个观察者都有一个update方法),做了什么,并且任何时候都能增删观察者,也不用改动主题的代码,主题只继承Observable抽象类,它只会给所有实现观察者接口的具体对象发送通知。改变其中一方并不会影响另一方,因为是松耦合的。

在这里插入图片描述
HeadFirst中提到另一个缺点是:主题继承了Observerable类,这是一个类,这个类甚至没有实现接口,那么就是不太符合针对接口编程设计原则的。一个主题类去继承它,如果这个类想拥有Observerable类和其他超类的行为,就不行,因为java不支持多重继承,这样就限制了Observerable类的复用。

二、代码实现

主题对象 也就是被观察的 Course

//course继承Observable类,成为被观察对象
public class Course extends Observable {

   private String courseName;

   public Course(String courseName) {
       this.courseName = courseName;
   }

   public String getCourseName() {

       return courseName;
   }

   //可以生产问题
   public void produceQuestion(Course course, Question question) {
       System.out.println(question.getUserName() +"在"+course.getCourseName()+"提交了一个问题");
       //setChanged()是Observable类提供的方法,代表状态发生了改变
       setChanged();       // changed = true;需要调用它使得通知开始运转,另外也有一个hasChanged()方法来获得当前change标志的状态
       //notifyObservers可传参也可以不传,这里把具体的问题传过去
       notifyObservers(question);
   }
}

观察者 Teacher

//老师观察的是课程而不是问题,问题是属于课程的
//观察者是teacher,被观察者是course(主题对象)
//teacher来实现Observer接口,这个接口只有update一个方法
public class Teacher implements Observer {
   private String teacherName;

   public Teacher(String teacherName) {
       this.teacherName = teacherName;
   }

   /**
    * @param o     被观察对象,也就是主题对象--在这里是course需要强转
    * @param arg   传参
    */
   @Override
   public void update(Observable o, Object arg) {
       Course course = (Course)o;
       Question question = (Question)arg;
       System.out.println(teacherName+"老师的" +course.getCourseName()+"课程接收到一个"
               +question.getUserName()+"同学的问题:"+question.getQuestionContent());
   }
}

Question类

public class Question {

   private String userName;    //提问者
   private String questionContent; //提问内容

   public String getUserName() {
       return userName;
   }

   public void setUserName(String userName) {
       this.userName = userName;
   }

   public String getQuestionContent() {
       return questionContent;
   }

   public void setQuestionContent(String questionContent) {
       this.questionContent = questionContent;
   }
}
public class Test {

    public static void main(String[] args) {
        Course softwareDesign = new Course("高级软件设计");
        Teacher teacher = new Teacher("潘敏学");

        softwareDesign.addObserver(teacher);

        //业务逻辑代码
        Question question = new Question();
        question.setUserName("小马哥");
        question.setQuestionContent("什么是观察者模式?");

        softwareDesign.produceQuestion(softwareDesign,question);
    }
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值