前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >观察者模式的使用

观察者模式的使用

作者头像
路行的亚洲
发布2021-06-24 14:15:29
4480
发布2021-06-24 14:15:29
举报
文章被收录于专栏:后端技术学习

观察者模式

观察者模式符合设计模式中的开闭原则,同时观察者模式在使用时可以随着系统的启动,起到刷新的作用。比如我们在系统启动的时候都会去查看和统计月结的耗材和药品的信息,此时就可以基于系统的启动去做一个月结数据的统计操作。同时在系统启动的时候,基于观察者模式实现对配置的实时加载。同时还可以对用户的数据信息进行实时加载,结合concurrentHashMap将用户的token信息进行放入,在登出的时候进行移除。说到底就是对配置信息、需要随系统启动而进行改变的数据进行统计的时候,此时就可以使用观察者模式。当然除此之外,基于观察者模式组合@PostConstruct注解启动一些定时任务或者服务。

Spring中的Refresh方法

为什么要讲refresh方法?

因为在refresh方法里面有一个重要的方法initApplicationMulticasterEvent这个方法,这个方法和我们在实现ApplicationEvent或者ApplicationListener接口的时候重写的onApplicationEvent这个方法息息相关。这个方法是实现multicastEvent中OnApplicationEvent的关键。

我们知道在ApplicationContext接口里面有一个操作刷新操作,不管是AnnotationConfigApplicationContext还是ClassPathXmlApplicationContext都会:

代码语言:javascript
复制
//基于注解式的上下文
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
    this();
    this.register(annotatedClasses);
    this.refresh();
}


// 基于xml的上下文
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

两者都有一个刷新操作,而这个刷新操作是在系统启动的时候就会进行加载的,这也是为什么在启动的时候可以对进行bean的配置装载和行为改变的关键。为止Spring提供了很多的扩展点,比如后置处理器、增强器和InitializingBean和Destory方法。也即在获取bean进行bean加载之后,如果想要对bean的行为进行扩展,也即必然需要借助它们来实现。那刷新方法能实现什么呢,同时需要什么条件呢?

首先如果需要进行扩展,首先需要有素材给我们扩展,这个和做菜是一样的。如果想要根据自己的口味做菜,首先要有 菜。也即在之前需要准备好需要刷新的上下文。这个类似于我们去饭馆吃菜的素材。

观察者模式在业务系统中的使用

在我目前做的系统中存在很多这样的场景,而这些场景都是基于观察者模式实现的:

比如我们自助称量、排床的过程中,我们需要对医院排床数据、医院编号会进行默认配置操作,此时就需要用到:

此时就会在项目启动的时候进行监听基于onApplicationEvent执行刷新操作,而这个实现的本质就是基于MulticasterEvent实现的,当产生Spring事件的时候会默认使用SimpleApplicationEventMulticaster的multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听器的处理。从而方便每次数据的获取后的组装。

代码语言:javascript
复制
 @Override
    public void onApplicationEvent(SysHospEvent event) {
        SysHospDTO dto = (SysHospDTO) event.getSource();
        // 新增医院时,复制默认排床显示配置到当前医院
        HdBedRecConf query = new HdBedRecConf();
        query.setFkHospId(SystemConstant.DEFAULT_SYS_HOSP_ID);
        List<HdBedRecConf> defaultConfList = listByCondition(query);
        if (CollectionUtils.isEmpty(defaultConfList)) {
            return;
        }
        // 清空默认配置的id,设置医院编号为当前医院
        defaultConfList.forEach(item -> {
            item.setId(null);
            item.setFkHospId(dto.getId());
            DataUtils.setAllSystemFieldValue(item);
        });
        hdBedRecConfMapper.insertList(defaultConfList);
    }

这是因为自助称量、体温单独起来一套系统,每一次都需要进行通信,而这个通信的过程也是一个数据在网络中来往的过程,因此需要借助Netty来完成这个操作。而这个操作过程中,自然需要一个客户端和一个服务端之间的操作,而这个过程是长连接的过程。涉及到编码和解码的过程、netty的通信过程中,对数据的处理。后面我们来了解netty的使用场景和在业务项目中的使用。

什么时候应该使用观察者模式

比如配置信息在系统启动的时候可以进行加载,此时可以使用。比如当前需要启动服务或者线程池或者定时任务时,可以使用观察者模式。比如我们需要对一些月结数据需要实时生产,每次启动系统的时候需要看指标数据,此时可以进行生成。比如对一些默认的配置信息需要在启动的时候基于观察者模式进行实时更新,此时可以使用观察者模式。

参考:

Spring源码深度解析 郝佳

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端技术学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 观察者模式
  • Spring中的Refresh方法
  • 观察者模式在业务系统中的使用
  • 什么时候应该使用观察者模式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档