编程思想-解耦实践

场景分类介绍

[TOC]

场景分类

责任链模式解耦

案例:当出现要用excel的规则逻辑来设计对同一个数据输入源进行处理时,发现规则而逻辑可以和线程控制分离,而这个分离器就是责任链模式,参考了汽车车轮和发动机直接用离合器的思想,再往下延伸离合器可以是手动挡,也可以是自动挡,自动挡离合器的原理是什么呢?

文件操作解耦

案例 cms的发布流程:模板文件和数据集成生成静态文件推送到ftp后,如何清理本地的副本文件.

初级方案:将删除文件流程加入到程序流程中,实现创建-传输-删除一体的事务管理,缺点,文件量大,过程较长导致线程占用资源较长,不利于高性能扩展,如果程序没有清理该文件将被忽略.

解耦方案:是将删除文件的操作交给定时任务执行shell,清除某个文件目录下的文件,直接批量删除,这样创建文件与删除文件就不用直接耦合到一起,清理文件批量高效,也不用占用IO资源.不会存在文件遗漏,而且在大批量文件操作性能更好.

mq实现解耦

案例:cms的失效页批量替换,也是涉及到批量文件的发布.

初级方案:如果全部在主线程中处理,将导致线程阻塞,主线程池无法及时释放会导致线程池爆仓,影响用户体验.

解耦方案:所以我采用了mq消息解耦,将批量文件替换的需求以消息形式发送,页面端请求线程快速返回.,用状态机来反馈处理结果.这样在处理大量的文件发布时,有消息队列堆积来完成消费,生产者只需要推消息.这种情况在电商系统中常用于秒杀,下单等高并发场景.

规则引擎,让控制和具体的业务逻辑解耦

没有具体案例,规则引擎也是一把双刃剑,适应场景有.

1、只有少量静态规则,并且不经常改变,不建议使用规则引擎;

2、需要在运行时动态修改规则,可考虑使用规则引擎;

3、在应用程序中需要通过可视化工具来修改规则,可考虑使用规则引擎;

4、规则需要非技术人员维护的情况下,可考虑使用规则引擎;

5、如果项目工期较紧,除非非常熟悉规则引擎,否则不建议使用;

6、如果使用Excel来管理规则,可考虑使用规则引擎;

xxl-job定时任务解耦

案例:将定时任务放入第三方中间件xxl-job中

初级方案:在服务中开启schedule,定时执行,这样的优点是当定时任务数量较少,单服有优势.对于分布式微服务集群场景就会有重复执行的bug.

解耦方案:避免了分布式集群下,任务重复执行的场景,job的生产端和执行端解耦,并发执行能力强.

常用的任务(定时发布主页/定时发布模块/定时创建新闻ES索引和文档入库)

数据同步操作解耦

案例:cms是有新老系统迁移的场景,在新闻业务上,有数据同步到老系统的业务,

初级方案:第一版本实现是将数据回写老系统直接耦合到业务逻辑,增加了业务复杂性.同步数据与业务逻辑耦合增加业务逻辑复杂性,而且不同的数据库操作保持一致性使用分布式事务非常麻烦.

解耦方案:数据同步这种跟业务逻辑关联并不大,只是数据同步要看需求:实时性/一致性/并发性/

同步操作会逐步退出业务逻辑,实时性要求并不高,只需要最终一致就行.就推荐使用streamset的dcd同步功能,使用易购系统,基于mysql的binlog日志实现数据的同步变更.

其他解耦方案:

在离线数据非实时同步场景,基于datax的离线数据同步

在业务复杂非实时场景:基于dts的实时在线数据同步

状态机解耦

案例:二手房贷款诈骗模型

需求背景:一批数据经过 税务局,房管局,银保监,公安局各个节点的逻辑过滤,打分(自有逻辑/外部服务数据同步打分),将高分者建立线索,通过对线索人员的社会轨迹和关系进行串并成嫌疑团伙,最后获得高分团伙.

初级方案:

按需求过程式编程,所有业务逻辑耦合,会导致业务逻辑复杂庞大,对局部的修改影响到全局,一旦某个节点无法提供数据整个程序无法执行.

解耦方案:

抽象实体:税务局处理,房管局处理,银保监处理,公安局处理.(工厂模式)

通用逻辑处理:获取数据列表->对数据进行评分->写入评分表.(模板模式)

控制器:获取待处理状态的数据批次->在工厂中获取列表->处理->更新数据批次状态,管理批次的节点任务执行状态.

这样一来,各个节点互相并不直接依赖,对单个的修改不会影响到其他工厂的变化(单一职责,开闭原则).

增加了控制器这个表和节点状态管理,将各个节点状态存储,执行任务要对状态进行判断.这样就实现了业务逻辑与控制的分离,如果要修改控制,不会对节点内的业务逻辑有影响,例如要变更控制逻辑,不需要动原有的业务代码,只需要在抽象父类工厂对控制方法变更.(模板方法的优势)

总结

通过上述解耦思想的案例场景可以得到,解耦的目的是为了可扩展性,对代码复杂度要求其实更高了,这是模块封装的一种思想.