设计模式:观察者模式

一、定义

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

二、场景

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

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

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

相关推荐
电子科技圈2 小时前
IAR与东软睿驰达成战略合作,强化软件开发效率与生态协作
设计模式·开源·软件工程·软件构建·代码规范·设计规范·代码复审
吴声子夜歌2 小时前
Java面试——设计模式(四)
java·设计模式·面试
吴声子夜歌19 小时前
Java面试——设计模式(一)
java·设计模式·面试
吴声子夜歌1 天前
Java面试——设计模式(二)
java·设计模式·面试
Larcher2 天前
SDD 项目开发步骤与提示词
人工智能·设计模式·架构
阿无,2 天前
设计模式之责任链模式
设计模式·责任链模式
云深处@2 天前
【C++设计模式】命令模式
c++·设计模式·命令模式
用户6919026813392 天前
Agent 上下文记忆原理
设计模式·架构·设计
Java后端的Ai之路2 天前
02、Python普通工厂模式
开发语言·人工智能·python·设计模式·普通工厂模式
Java后端的Ai之路2 天前
01、Python - 设计模式介绍
java·人工智能·python·设计模式·通用