溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何用java設(shè)計(jì)系統(tǒng)

發(fā)布時(shí)間:2021-11-16 11:26:38 來源:億速云 閱讀:163 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“如何用java設(shè)計(jì)系統(tǒng)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何用java設(shè)計(jì)系統(tǒng)”吧!

- 系統(tǒng)基本面


信息獲取
	1. 調(diào)用外部系統(tǒng)接口,通過mq異步返回?cái)?shù)據(jù); 如征信系統(tǒng)、第三方平臺(tái)風(fēng)控系統(tǒng)等 
	2. 調(diào)用當(dāng)前應(yīng)用緩存數(shù)據(jù);如redis or db;
節(jié)點(diǎn)數(shù)據(jù)判別
	1.需對某些節(jié)點(diǎn)返回的數(shù)據(jù)進(jìn)行判別,跳轉(zhuǎn)節(jié)點(diǎn)
	2.每個(gè)節(jié)點(diǎn)需對c端做功能處理產(chǎn)生的數(shù)據(jù)和流程中的節(jié)點(diǎn)狀態(tài)扭轉(zhuǎn)日志進(jìn)行落地(人行征信拒絕、等待擔(dān)保人提交問卷等)

- 系統(tǒng)需求:


1. 流程可配置化 ——— 應(yīng)對業(yè)務(wù)快速發(fā)展
2. 每個(gè)功能點(diǎn)進(jìn)行模塊化
優(yōu)勢:1.功能單一,開發(fā)人員需求清晰、責(zé)任分明;
     2.容易對某個(gè)功能進(jìn)行復(fù)用、擴(kuò)展和測試

- 系統(tǒng)設(shè)計(jì)


流程工廠 — 根據(jù)不同資質(zhì)的用戶有相應(yīng)的風(fēng)控流程

<!-- 流程工廠 -->
<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>

截止目前為止,已經(jīng)滿足了上面所提到的需求;這種有點(diǎn)偏類似于工作流的模式;

操作步驟
1.當(dāng)請求到該系統(tǒng)時(shí),系統(tǒng)根據(jù)入?yún)⑦x擇相應(yīng)的流程;
2.循環(huán)調(diào)用該流程中的每個(gè)handler進(jìn)行處理;

通過handler 接口的演化,可以類似于責(zé)任鏈的模式;以往工作經(jīng)歷中有使用過類似的設(shè)計(jì)方式;當(dāng)時(shí)戲稱為工作流+責(zé)任鏈模式;

------------

but .... 系統(tǒng)遠(yuǎn)沒有如此簡單;上面可以簡稱為 toy code;

根據(jù)業(yè)務(wù)發(fā)展,我們發(fā)現(xiàn)每個(gè)handler有自己的特性,分為以下幾點(diǎn):
1. 普通handler;按照指定的順序,執(zhí)行完功能方法就可以執(zhí)行下一個(gè)了;
1. 判別handler;根據(jù)當(dāng)前handler處理的情況;該flow的執(zhí)行流程會(huì)發(fā)生如下改變:
- - 終結(jié)態(tài),當(dāng)前線程的鏈路執(zhí)行結(jié)束; egg: a -> b -> c -> d  ===>> a -> b
- - 節(jié)點(diǎn)的跳轉(zhuǎn);egg:a -> b -> c -> d  ===>> a -> b -> d
- - 如普通handler一樣,順序執(zhí)行下一個(gè)handler;

而且每個(gè)handler可能會(huì)對流程中產(chǎn)生的數(shù)據(jù)進(jìn)行入庫操作和日志記錄等操作; handler接口定義:

public interface ProcessHandler<T> {
    /**
     * handler處理主方法
     *
     * @param reqParam
     * @return
     */
    T process(ReqParam reqParam);

    /**
     * 該handler的下一個(gè)handler處理的下標(biāo)
     *
     * @param reqParam
     * @param flow
     * @return
     */
    default int nextHanderIndex(ReqParam reqParam, Flow flow) {
        return flow.getNextHandlerIndex(getBeanName());
    }

    /**
     * 判斷該handler是否需要將數(shù)據(jù)更新庫中
     *
     * @return
     */
    default boolean updateDb() {
        return true;
    }

    /**
     * 獲取handler類名
     */
    String getBeanName();

}
  • process method —— 執(zhí)行該handler的功能體

  • nextHanderIndex —— 返回該handler處理完后的下一個(gè)handler下標(biāo)

  • updateDb —— 判斷該hander是否有數(shù)據(jù)進(jìn)行落庫

  • getBeanName —— 獲取該handler的bean id

這里有一個(gè)小的技巧;雖然flow包含一個(gè)handler集合;但flow和handler之間仍然是低耦合的;當(dāng)判斷下一個(gè)handler下標(biāo)的時(shí)候,并非交給該handler去決定;而是交回給執(zhí)行該handler的flow去處理;防止handler和某個(gè)flow強(qiáng)耦合;

某個(gè)handler實(shí)現(xiàn)片段代碼:

@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 參數(shù)列表
     * 
     */
    @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 抽象類執(zhí)行片段:

@Data
public abstract class BaseFlow implements Flow {

    Map<Integer, ProcessHandler> handlerMap;
    private int length;
    /**
     * 當(dāng)前flow中的handler bean name 對應(yīng)的執(zhí)行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開始執(zhí)行相應(yīng)的handler處理器
     *
     * @param index
     * @param reqParam
     */

    @Override
    public void execute(int index, ReqParam reqParam) {

        while (index < length) {
            ProcessHandler handler = handlerMap.get(index);
            handler.process(reqParam);

            // 是否對數(shù)據(jù)進(jìn)行落庫操作
            boolean flag = handler.updateDb();
            if (flag) {
                getDataUtil().updateData(reqParam);
            }

            // 判斷該handler處理完是否終結(jié)
            boolean endFlag = reqParam.isEnd();
            if (endFlag) {
                return;
            }

            index = handler.nextHanderIndex(reqParam, this);
        }
    }

    abstract DataUtil getDataUtil();
		...
}

執(zhí)行順序:

  • 獲取從第幾個(gè)handler開始執(zhí)行,開始時(shí),從第0個(gè)handler開始處理;但當(dāng)調(diào)用外部接口時(shí),通過mq異步返回,則需指定從第幾個(gè)handler開始執(zhí)行;

  • 判斷執(zhí)行的handler是否需要存儲(chǔ)數(shù)據(jù)庫或緩存

  • 判斷當(dāng)前handler是否為終結(jié)狀態(tài);該鏈接完全結(jié)束

  • 獲取下一個(gè)需要執(zhí)行的handler下標(biāo);

感謝各位的閱讀,以上就是“如何用java設(shè)計(jì)系統(tǒng)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何用java設(shè)計(jì)系統(tǒng)這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI