重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要讲解了“如何用java设计系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何用java设计系统”吧!
成都创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站建设、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的福清网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
信息获取 1. 调用外部系统接口,通过mq异步返回数据; 如征信系统、第三方平台风控系统等 2. 调用当前应用缓存数据;如redis or db;
节点数据判别 1.需对某些节点返回的数据进行判别,跳转节点 2.每个节点需对c端做功能处理产生的数据和流程中的节点状态扭转日志进行落地(人行征信拒绝、等待担保人提交问卷等)
1. 流程可配置化 ——— 应对业务快速发展 2. 每个功能点进行模块化 优势:1.功能单一,开发人员需求清晰、责任分明; 2.容易对某个功能进行复用、扩展和测试
流程工厂 — 根据不同资质的用户有相应的风控流程
功能模块定义...
流程 - handler组装
截止目前为止,已经满足了上面所提到的需求;这种有点偏类似于工作流的模式;
操作步骤 1.当请求到该系统时,系统根据入参选择相应的流程; 2.循环调用该流程中的每个handler进行处理;
通过handler 接口的演化,可以类似于责任链的模式;以往工作经历中有使用过类似的设计方式;当时戏称为工作流+责任链模式;
------------
but .... 系统远没有如此简单;上面可以简称为 toy code;
根据业务发展,我们发现每个handler有自己的特性,分为以下几点: 1. 普通handler;按照指定的顺序,执行完功能方法就可以执行下一个了; 1. 判别handler;根据当前handler处理的情况;该flow的执行流程会发生如下改变: - - 终结态,当前线程的链路执行结束; egg: a -> b -> c -> d ===>> a -> b - - 节点的跳转;egg:a -> b -> c -> d ===>> a -> b -> d - - 如普通handler一样,顺序执行下一个handler;
而且每个handler可能会对流程中产生的数据进行入库操作和日志记录等操作; handler接口定义:
public interface ProcessHandler{ /** * handler处理主方法 * * @param reqParam * @return */ T process(ReqParam reqParam); /** * 该handler的下一个handler处理的下标 * * @param reqParam * @param flow * @return */ default int nextHanderIndex(ReqParam reqParam, Flow flow) { return flow.getNextHandlerIndex(getBeanName()); } /** * 判断该handler是否需要将数据更新库中 * * @return */ default boolean updateDb() { return true; } /** * 获取handler类名 */ String getBeanName(); }
process method —— 执行该handler的功能体
nextHanderIndex —— 返回该handler处理完后的下一个handler下标
updateDb —— 判断该hander是否有数据进行落库
getBeanName —— 获取该handler的bean id
这里有一个小的技巧;虽然flow包含一个handler集合;但flow和handler之间仍然是低耦合的;当判断下一个handler下标的时候,并非交给该handler去决定;而是交回给执行该handler的flow去处理;防止handler和某个flow强耦合;
某个handler实现片段代码:
@Slf4j public class AaaQueryHandler implements ProcessHandler{ private static final String AAA_REJECT = "aaa_reject"; private static final String BEAN_NAME = "aaaQuery"; @Resource private Service riskService; /** * @param reqParam 参数列表 * */ @Override public Void process(ReqParam reqParam) { RiskAdmittanceQueryParams param = reqParam.getParams(); ... reqParam.putEle(ReqParam.UPDATE_TYPE, UpdateDataType.UPDATE_BUSINESS); reqParam.putEle(AAA_REJECT, true); return null; } @Override public int nextHanderIndex(ReqParam reqParam, Flow flow) { boolean aaaReject = reqParam.getEle(AAA_REJECT); return flow.judgeAaa(aaaReject, BEAN_NAME); } @Override public String getBeanName() { return BEAN_NAME; } }
flow 抽象类执行片段:
@Data public abstract class BaseFlow implements Flow { MaphandlerMap; private int length; /** * 当前flow中的handler bean name 对应的执行number */ public Map numberOfHandlerMap; public void init() { length = handlerMap.size(); numberOfHandlerMap = handlerMap.entrySet() .stream() .collect(Collectors.toMap(entry -> entry.getValue().getBeanName(), Map.Entry::getKey)); } /** * 从该flow中指定的index开始执行相应的handler处理器 * * @param index * @param reqParam */ @Override public void execute(int index, ReqParam reqParam) { while (index < length) { ProcessHandler handler = handlerMap.get(index); handler.process(reqParam); // 是否对数据进行落库操作 boolean flag = handler.updateDb(); if (flag) { getDataUtil().updateData(reqParam); } // 判断该handler处理完是否终结 boolean endFlag = reqParam.isEnd(); if (endFlag) { return; } index = handler.nextHanderIndex(reqParam, this); } } abstract DataUtil getDataUtil(); ... }
执行顺序:
获取从第几个handler开始执行,开始时,从第0个handler开始处理;但当调用外部接口时,通过mq异步返回,则需指定从第几个handler开始执行;
判断执行的handler是否需要存储数据库或缓存
判断当前handler是否为终结状态;该链接完全结束
获取下一个需要执行的handler下标;
感谢各位的阅读,以上就是“如何用java设计系统”的内容了,经过本文的学习后,相信大家对如何用java设计系统这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!