设计模式——观察者

1. 定义

定义了对象之间一对多依赖,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。
观察者依赖于主题,只要主题状态一有变化,观察者就会被通知。
观察者是一种行为型模式

2. 类图

请添加图片描述
类图说明:

  1. 对象使用主题接口将自己注册为观察者,或者把自己从观察者中删除。
  2. 一个具体的主体总是实现主体接口,除了注册和删除方法之外,还实现了 notifyObservers()方法,此方法用于在状态改变时更新所有观察者。
  3. 具体主题也可能有设置和获取状态的方法。
  4. 每个主题可以有多个观察者。
  5. 所有的观察者必须实现观察者接口,这个接口只有update()一个方法,当主题状态改变时他被调用。
  6. 具体的观察者可以是实现观察者接口的任意类。观察者必须注册具体类,以便接受更新。

3. 应用

实现一个简单的账单显示,账单面板BillPanel中可以添加删除账单Bill,有两个观察者面板,一个时TotalMoneyPanel用来显示总金额,一个时InterestMoneyPanel用来显示利息。当BillPanel中添加账单和删除账单时,就会通知观察者,显示总金额和利息的面板就会自动更新。

类图

请添加图片描述

代码

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
public interface Observer {
    void update(double moneyChange);
}
public class Bill {
    private String name;
    private double money;
    Bill(String name, double money) {
        this.name=name;
        this.money=money;
    }
    double getMoney() {
        return money;
    }
}
public class BillPanel implements Subject{
    private List<Bill> bills;
    private List<Observer> observers;
    public BillPanel() {
        this.bills=new ArrayList<>();
        this.observers=new ArrayList<>();
    }
    public void addBill(Bill bill){
        bills.add(bill);
        notifyObservers();
    }
    public void removeBill(Bill bill){
        bills.remove(bill);
        notifyObservers();
    }
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    @Override
    public void notifyObservers() {
        double totalMoney= bills.stream().mapToDouble(Bill::getMoney).sum();
        observers.forEach(observer -> observer.update(totalMoney));
    }
}
public class InterestMoneyPanel implements Observer {
    private Subject subject;
    private double interestMoney;

    public InterestMoneyPanel(Subject subject) {
        this.subject = subject;
        subject.registerObserver(this);

    }
    @Override
    public void update(double moneyChange) {
        this.interestMoney = moneyChange;
        display();
    }
    private void display() {
        System.out.println("利息是: " + interestMoney * 0.04);
    }
}
public class TotalMoneyPanel implements Observer{
    private double totalMoney;
    private Subject subject;

    public TotalMoneyPanel(Subject subject) {
        this.subject = subject;
        subject.registerObserver(this);

    }
    @Override
    public void update(double moneyChange) {
        this.totalMoney=moneyChange;
        display();
    }
    public void display(){
        System.out.println("总金额:"+totalMoney);
    }
}
public class Test {
    public static void main(String[] args) {
        //主题
        BillPanel billPanel=new BillPanel();
        //观察者
        InterestMoneyPanel interestMoneyPanel=new InterestMoneyPanel(billPanel);
        TotalMoneyPanel totalMoneyPanel=new TotalMoneyPanel(billPanel);

        Bill bill1=new Bill("1",200);
        Bill bill2=new Bill("2",300);
        Bill bill3=new Bill("3",100);
        billPanel.addBill(bill1);
        billPanel.addBill(bill2);
        billPanel.addBill(bill3);
        billPanel.removeBill(bill2);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值