一个欲儿的博客

一个欲儿的博客

监听器模式
2025-07-01

1. 问题背景

假设我们有一个 银行账户管理系统,该系统需要监控用户账户余额的变动,并在发生变动时,自动执行一些相关的操作,比如发送 余额变动通知(如短信、邮件等)。为了实现这一功能,我们希望通过一个灵活且松耦合的方式来处理余额变动通知。

2. 监听器

这个问题当中,当用户的余额发生变化的一瞬间,我们就希望执行发送短信、邮件等功能,在你不知道监听器的时候,你也许会直接在用户余额发生变化的时候把相应的业务逻辑写在那里,这样有好处但是也有坏处,好处就是代码逻辑性强,坏处就是高耦合且不好维护

所以想到余额变化的时候代码那个地方只调用有一个接口,真正执行的时候再把实现注入进去,这个就是监听器

3. 手搓代码环节

3.1 项目结构

image.png

3.2 AccountBalanceListener

public interface AccountBalanceListener {
    void onBalanceChange(double newBalance);  // 余额变化时的响应方法 可以设置发短信或者邮件
}

3.3 BalanceChangeNotifier

public class BalanceChangeNotifier implements AccountBalanceListener{

    @Override
    public void onBalanceChange(double newBalance) {
        // 假设发送一条通知(如发送短信或电子邮件)
        System.out.println("发送邮件 新的余额是:" + newBalance);
    }
}

3.4 BankAccount

public class BankAccount {
    private double balance;  // 账户余额
    private AccountBalanceListener listener;  // 持有监听器的引用

    // 构造方法
    public BankAccount(double balance) {
        this.balance = balance;
    }

    // 设置余额监听器
    public void setListener(AccountBalanceListener listener) {
        this.listener = listener;
    }

    // 修改余额
    public void changeBalance(double amount) {
        this.balance += amount;  // 更新余额
        if (listener != null) {
            listener.onBalanceChange(this.balance);  // 触发余额变化事件
        }
    }

    // 获取当前余额
    public double getBalance() {
        return balance;
    }
}

3.5 Main

public class Main {
    public static void main(String[] args) {
        // 创建银行账户对象
        BankAccount account = new BankAccount(1000.0);

        // 创建余额变动通知器
        BalanceChangeNotifier notifier = new BalanceChangeNotifier();

        // 设置账户的余额监听器
        account.setListener(notifier);

        // 模拟账户余额变动
        account.changeBalance(-200.0);
        account.changeBalance(500.0);
    }
}

4. 总结

4.1 运行截图

image.png

4.2 一些心得

监听器和观察者有点像,但还是有不同的

  1. 监听器是状态发生变化立刻就执行业务逻辑,观察者则是状态发生变化只是通知各个订阅者,状态发生变化了,业务逻辑还需要他们自己去执行

  2. 监听器往往是1对1,观察者则是1对多 监听器往往用于ui相关,比如按钮的单击事件,观察者更多的是偏向于业务逻辑相关

4.3 A i有话说

image.png



发表评论: