设计模式(19)-观察者模式

简介

为什么要使用观察者模式

在软件系统中,对象和对象之间可能存在着这样的一对多的关系:当一个对象发生改变,它的相关对象也都会随之发生改变。观察者模式描述这样的一种关联关系。

观察者模式应用非常广泛,是使用频率最高的设计模式之一,我们应该着重学习这个设计模式。

什么是观察者模式

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

别名

  • 发布-订阅(Publish/Subscribe)模式
  • 模型-视图(Model/View)模式
  • 源-监听器(Source/Listener)模式
  • 依赖(Dependents)模式

类型

对象行为型模式

遵守的原则

迪米特法则、开闭原则

使用频率

★★★★★

角色

角色

  • Subject:抽象目标类
    • 抽象类
    • 具体目标类的父类。
    • 被观察的对象。
    • 定义了一个观察者集合,并提供方法来增加和删除观察者。
    • 定义了通知方法。
  • ConcreteSubject:具体目标类
    • 具体类
    • 继承了抽象目标类。
    • 包含经常发生改变的数据。
    • 目标类在某些情况下可以省略。
  • Observer:抽象观察者
    • 接口
    • 对观察目标的改变做出相应。
    • 声明了更新的方法。
  • ConcreteObserver:具体观察者
    • 具体类
    • 实现了抽象观察者。
    • 维护了一个目标对象ConcreteSubject的引用。
    • 实现了抽象观察者的更新方法。
    • 可以将自己添加到目标类的观察者集合中或将自己从其中删除。

UML类图

MarkdownPhotos/master/CSDNBlogs/DesignPatterns/observer.png

代码实现

  • 新建抽象目标类Subject.java
  • 新建具体目标类ConcreteSubject.java
  • 新建抽象观察者Observer.java
  • 新建具体观察者ConcreteObserver.java
  • 新建测试类Client.java

抽象目标类
Subject.java

abstract class Subject {
    // 定义一个观察者集合用于存储所有观察者对象
    protected ArrayList<Observer> observers = new ArrayList<Observer>();
    // 观察者状态
    int subjectState;

    public int getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(int subjectState) {
        this.subjectState = subjectState;
    }

    // 注册方法,用于向观察者集合中增加一个观察者
    public void attach(Observer observer) {
        observers.add(observer);
    }

    // 注销方法,用于在观察者集合中删除一个观察者
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    // 声明抽象通知方法
    public abstract void notifyObserver();
}

具体目标类
ConcreteSubject.java

class ConcreteSubject extends Subject {

    // 实现通知方法
    @Override
    public void notifyObserver() {
        // 遍历观察者集合,调用每一个观察者的响应方法
        for (Object obs : observers) {
            ((Observer) obs).update(this);
        }
    }
}

抽象观察者
Observer.java

interface Observer {
    // 声明响应方法
    public void update(Subject sub);
}

具体观察者
ConcreteObserver.java

class ConcreteObserver implements Observer {
    // 观察者名称
    String name;
    // 观察者状态
    int obeserverState;

    // 实现响应方法
    public ConcreteObserver(String name) {
        super();
        this.name = name;
    }

    @Override
    public void update(Subject sub) {
        obeserverState = sub.getSubjectState();
        System.out.println("update oberserver[" + name + "] state:" + obeserverState);
    }
}

测试类
Client.java

public class Client {
    public static void main(String[] args) {

        Subject subject = new ConcreteSubject();
        Observer objA = new ConcreteObserver("A");
        Observer objB = new ConcreteObserver("B");
        subject.attach(objA);
        subject.attach(objB);

        subject.setSubjectState(1);
        subject.notifyObserver();

        subject.detach(objB);
        subject.setSubjectState(2);
        subject.notifyObserver();
    }
}

测试
运行Client.java的main()

update oberserver[A] state:1
update oberserver[B] state:1
update oberserver[A] state:2

优缺点

优点

  • 遵守“开闭原则”。新增新的观察者和观察目标不需要修改系统原有代码。
  • 遵守“迪米特法则”。观察者和目标是抽象耦合的。目标只是维持了一个观察者的集合,而不知道任何一个观察者是属于哪个具体的类的。这样目标和观察者之间的耦合是最小的。
  • 支持广播通信。目标发送的通知不需要指定它的接受者。

缺点

待补充

适用环境

当一个对象发生改变,它的相关对象也都会随之发生改变,而不知道它的关联对象有多少个。

使用场景

待补充

扩展

目标和观察者之间可以存在中介者。

问题

Java中,JDK对观察者模式的实现有哪些类,请说明?

待补充。

观察者模式与MVC有什么关系?

待补充。

在软件开发中,你在哪里用到了观察者模式?

待补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值