设计模式:观察者模式

一、定义

目标对象与观察者对象之间是一对多的依赖关系,当目标对象发生变化时,它所有依赖对象都会收到通知并更新。又叫发布订阅模式,属于行为型模式。

二、场景

一个对象的改变将导致多个对象发生改变。

一个对象状态发生改变并且必须通知其他对象,却并不知道这些对象是谁。

具体的如邮件订阅、Swing中的事件监听、红绿灯、股票行情等

三、例子

使用jdk实现邮件订阅,模拟场景是客户A和客户B都订阅了瑞幸的邮件通知,瑞幸新品发布给客户推送邮件

定义一个邮件类

java 复制代码
public class Email {
    private String title;//标题
    private String content;//内容
    private String from;//发送者

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }
}

创建一个被观察者,在这里就是邮箱了

java 复制代码
public class EmailBox extends Observable {

    private String name = "QQ邮箱";

    private static EmailBox emailBox = null;
    private EmailBox() {}

    public static EmailBox getInstance() {
        if(emailBox == null) {
            emailBox = new EmailBox();
        }
        return emailBox;
    }

    public String getName() {
        return name;
    }

    public void sendEmail(Email email) {
        System.out.println(email.getFrom() + "发送了邮件:" + email.getTitle());
        setChanged();
        notifyObservers(email);
    }
}

再创建一个观察者,在这里就是客户了

java 复制代码
public class Custom implements Observer {
    private String name;

    public Custom(String name) {
        this.name = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        EmailBox emailBox = (EmailBox) o;
        Email email = (Email) arg;
        System.out.println("********** " + name + " **********");
        System.out.println("您的【" + emailBox.getName() + "】收到一封邮件:\n"
                + "邮件标题:" + email.getTitle() + "\n"
                + "来自:" + email.getFrom() + "\n"
                + "内容:" + email.getContent());
    }
}

好了,下面是测试类

java 复制代码
public class Test {
    public static void main(String[] args) {
        EmailBox emailBox = EmailBox.getInstance();
        Custom customA = new Custom("客户A");
        Custom customB = new Custom("客户B");

        Email email = new Email();
        email.setFrom("瑞幸");
        email.setTitle("十二月新品上市");
        email.setContent("酱香拿铁,欢迎品尝");
        emailBox.addObserver(customB);
        emailBox.addObserver(customA);
        emailBox.sendEmail(email);
    }
}

//运行结果
/*
瑞幸发送了邮件:十二月新品上市
********** 客户A **********
您的【QQ邮箱】收到一封邮件:
邮件标题:十二月新品上市
来自:瑞幸
内容:酱香拿铁,欢迎品尝
********** 客户B **********
您的【QQ邮箱】收到一封邮件:
邮件标题:十二月新品上市
来自:瑞幸
内容:酱香拿铁,欢迎品尝
 */

四、优缺点

优点:

1.目标与观察者之间是抽象耦合关系

2.支持广播通信

缺点:

1.较多的观察者可能导致低效,同时过多的细节依赖增加了复杂性

2.目标与观察者之间的循环依赖,会导致死循环,要避免循环调用

相关推荐
蓝天居士4 小时前
软考 系统架构设计师系列知识点 —— 设计模式之抽象工厂模式
设计模式·系统架构·抽象工厂模式
cherry52304 小时前
【Java设计模式】第1章 课程导学
java·开发语言·设计模式
电子科技圈6 小时前
IAR推动嵌入式开发:云就绪、可扩展的CI/CD和可持续自动化
嵌入式硬件·设计模式·自动化·软件工程·软件构建·设计规范
自在如风。7 小时前
Java 设计模式:责任链模式详解
java·设计模式·责任链模式
马达加斯加D8 小时前
设计模式 --- 观察者模式
java·观察者模式·设计模式
钢板兽8 小时前
Java常见的23种设计模式
java·开发语言·设计模式
渊渟岳8 小时前
分享个人设计模式笔记文档:《掌握设计模式:23种经典模式实践、选择、价值与思想》
设计模式
01空间19 小时前
设计模式简述(七)原型模式
设计模式
程序员JerrySUN19 小时前
设计模式 Day 4:观察者模式(Observer Pattern)深度解析
javascript·观察者模式·设计模式
狼哥IKOO1 天前
AI 终端模拟器 Python 脚本
后端·设计模式·github