设计模式:观察者模式

一、定义

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

二、场景

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

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

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

相关推荐
mooridy25 分钟前
设计模式 | 详解常用设计模式(六大设计原则,单例模式,工厂模式,建造者模式,代理模式)
c++·设计模式
程序员JerrySUN28 分钟前
设计模式每日硬核训练 Day 17:中介者模式(Mediator Pattern)完整讲解与实战应用
microsoft·设计模式·中介者模式
Auroral1563 小时前
结构型模式:装饰器模式
设计模式
智想天开3 小时前
14.外观模式:思考与解读
windows·microsoft·设计模式·外观模式
摘星编程5 小时前
并发设计模式实战系列(9):消息传递(Message Passing)
设计模式·并发编程
此木|西贝13 小时前
【设计模式】享元模式
java·设计模式·享元模式
麓殇⊙15 小时前
设计模式--建造者模式详解
设计模式·建造者模式
不当菜虚困15 小时前
JAVA设计模式——(八)单例模式
java·单例模式·设计模式
Java致死15 小时前
工厂设计模式
java·设计模式·简单工厂模式·工厂方法模式·抽象工厂模式
全栈凯哥17 小时前
桥接模式(Bridge Pattern)详解
java·设计模式·桥接模式