设计模式:观察者模式

一、定义

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

二、场景

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

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

具体的如邮件订阅、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.目标与观察者之间的循环依赖,会导致死循环,要避免循环调用

相关推荐
Patrick_Wilson6 小时前
青苔漫染待客迟
前端·设计模式·架构
易元14 小时前
设计模式-模板方法模式
后端·设计模式
花好月圆春祺夏安15 小时前
基于odoo17的设计模式详解---策略模式
设计模式·策略模式
收破烂的小熊猫~1 天前
《Java修仙传:从凡胎到码帝》第四章:设计模式破万法
java·开发语言·设计模式
佛祖让我来巡山1 天前
【工厂和策略设计模式妙用】解决接口选择与多重if-else 问题
设计模式·策略模式·工厂模式
hqxstudying1 天前
Java创建型模式---原型模式
java·开发语言·设计模式·代码规范
WebInfra1 天前
如何在程序中嵌入有大量字符串的 HashMap
算法·设计模式·架构
Gavynlee2 天前
plantuml用法总结
设计模式
DKPT2 天前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
缘来是庄2 天前
设计模式之迭代器模式
java·设计模式·迭代器模式