温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何用java设计系统

发布时间:2021-11-16 11:26:38 来源:亿速云 阅读:151 作者:iii 栏目:大数据

这篇文章主要讲解了“如何用java设计系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何用java设计系统”吧!

- 系统基本面


信息获取
	1. 调用外部系统接口,通过mq异步返回数据; 如征信系统、第三方平台风控系统等 
	2. 调用当前应用缓存数据;如redis or db;
节点数据判别
	1.需对某些节点返回的数据进行判别,跳转节点
	2.每个节点需对c端做功能处理产生的数据和流程中的节点状态扭转日志进行落地(人行征信拒绝、等待担保人提交问卷等)

- 系统需求:


1. 流程可配置化 ——— 应对业务快速发展
2. 每个功能点进行模块化
优势:1.功能单一,开发人员需求清晰、责任分明;
     2.容易对某个功能进行复用、扩展和测试

- 系统设计


流程工厂 — 根据不同资质的用户有相应的风控流程

<!-- 流程工厂 -->
<bean id="flowFactory" class="com.souche.risk.admittance.executor.FlowFactory">
    <property name="flowMap">
        <map>
            <entry key="xxxFlow" value-ref="xxxFlow"/>
			...
        </map>
    </property>
</bean>
功能模块定义

    <!-- 征信查询 -->
    <bean id="aaa"
          class="com.souche.risk.admittance.executor.handle.AaaHandler"/>

    <!-- 额度查询 -->
    <bean id="bbb"
          class="com.souche.risk.admittance.executor.handle.BbbHander"/>
	...
流程 - handler组装
 <bean id="guaranteeFlow" class="com.souche.risk.admittance.executor.GuaranteeFlow" init-method="init">
        <property name="handlerMap">
            <map>
                <entry key="0" value-ref="aaa"  />
                <entry key="1" value-ref="bbb" />
				...
            </map>

        </property>
    </bean>

截止目前为止,已经满足了上面所提到的需求;这种有点偏类似于工作流的模式;

操作步骤
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<T> {
    /**
     * 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<Void> {

    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 {

    Map<Integer, ProcessHandler> handlerMap;
    private int length;
    /**
     * 当前flow中的handler bean name 对应的执行number
     */
    public Map<String, Integer> 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设计系统这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI