java 观察者模式的实现及应用场景

最近项目中有个合同拆分功能,涉及到多个参数的联动,为了能更高效的实现该功能,我决定用观察者设计模式来完成这个功能。之前只是在网上了解过,具体实现细节已经忘光了,在这里写个小demo简单回忆一下

(这里我是用的java内置的observable和observer类来实现的)

1.首先创建被观察者:

import java.util.ArrayList;
import java.util.Observable;

/**
 * @Des: 被观察者
 * @Author: liut 
 * @Date: 2021/3/22 17:12
 */
public class ContractData extends Observable{

    private double total;
    private double selfImposedPartAmount ;
    private double provisionalEstimate;
    private String name;
    public ArrayList observables;

    public ContractData(){
        observables = new ArrayList();
    }


    //从数据源收到数据后,更新自己的数据,并且把数据发给各个观察者
    public void setChangeData(double total,double selfImposedPartAmount,double provisionalEstimate, String name){
        this.total = total;
        this.selfImposedPartAmount = selfImposedPartAmount;
        this.provisionalEstimate = provisionalEstimate;
        this.name = name;
        dataChange();
    }

    //把变动数据发送给各个观察者
    private void dataChange() {
        setChanged();//这一步必须有
        notifyObservers();
    }

    public double getTotal() {
        return total;
    }

    public double getSelfImposedPartAmount() {
        return selfImposedPartAmount;
    }

    public double getProvisionalEstimate() {
        return provisionalEstimate;
    }

    public String getName() {
        return name;
    }
}

2.然后创建观察者:

import java.util.Observable;
import java.util.Observer;

/**
 * @Des: 观察者
 * @Author: liut 
 * @Date: 2021/3/22 17:06
 */
public class Contract implements Observer,DisplayData {

    private double total;
    private double selfImposedPartAmount ;
    private double provisionalEstimate;
    private String name;
    private Observable observable;

    //当构建观察者时,指定数据源
    public Contract(Observable contractData, String name){
        this.observable = contractData;
        this.name = name;
        observable.addObserver(this);//注册到观察者列表
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof ContractData){
            ContractData contractData = (ContractData) o;
            this.total = contractData.getTotal();
            this.selfImposedPartAmount = contractData.getSelfImposedPartAmount();
            this.provisionalEstimate = contractData.getProvisionalEstimate();
            this.name = contractData.getName();
            display();//数据更新已同步,应该做出相应的数据处理,这里只简单打印变动后的数据
        }
    }

    @Override
    public void display() {
        System.out.println("name:" + name + "  total:"+total+"  selfImposedPartAmount:"+selfImposedPartAmount+"  provisionalEstimate:"+provisionalEstimate);
    }
}

3.方法测试:

public class ContractObserverMain {
    public static void main(String[] args) {
        ContractData contractData = new ContractData();
        Contract contract1 = new Contract(contractData, "合同1");
        contractData.setChangeData(1,2,3,"合同1");
    }
}

在这里插入图片描述

其中被观察者中把变动数据发送给各个观察者里有个步骤必须存在:

在这里插入图片描述
这一步是将java内置的observable类里的changed参数设值:
在这里插入图片描述
如果没有这一步,那notifyObservers()方法就不能成功执行,新数据就无法同步到各个观察者:
在这里插入图片描述

开发中常见的场景:

1.聊天室中,服务器转发消息给客户端
2.项目中群发某条消息
3.监听器的实现
4.消息订阅
案例:比如公众号会不定时发布一些消息,关注的用户就可以收到推送消息,取消关注就收不到推送消息。

因为项目中会涉及到多线程的问题,所以会对上面的流程进行优化,等项目功能实现完全之后,我会写个涉及线程池及并发问题的观察者模式博客。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值