隨著需求不斷迭代,轉轉消費分期整體出現了一些調整,并提出了新的產品方向,在此背景下,對于經歷了久經滄桑的歷史服務,已經逐漸不適合未來的產品規劃。面對新的業務整合和重組,急需新的架構和思想來承載未來的業務。
現階段存在的主要問題:
即使我們接手項目已經有一段時間,并對項目足夠了解時,但排查問題起來依然費力費時,而且系統內部代碼錯綜復雜,調用鏈路交錯,難以正常維護,從長遠的開發效率考慮,盡快提出新型方案來代替現有結構。
線上異常機制不夠敏感,缺少關鍵業務指標的告警看板,作為一個業務開發,應保持對核心指標數據的敏感性。
開始重構之前,調研了互聯網消金通用的架構解決方案:
通用方案
由于是外部調研的通用架構設計,所以并非完全契合轉轉消費分期產品,但可以借鑒其分層架構設計的思想,在代碼設計階段,可以先對核心模塊進行拆解和規劃。
前端頁面與后端重構計劃分兩次迭代進行,分階段進行,可以有效分攤并降低項目上線風險,第一次迭代圍繞后端主要模塊進行剝離重新設計并上線;第二次重構目的是解決產品需求,對接前端新頁面。
作為一個一線的業務開發,需要開展重構工作的同時還得保證產品需求的正常迭代,修繕者模式無疑是最佳選擇。 第一次迭代歷程,對于歷史工程邊緣邏輯保留并隔離,只對核心代碼進行重構后轉移到到新工程,新工程逐步接手老舊邏輯,并對老工程提供RPC接口,逐漸取代。此方案整體風險最低,同時能兼顧到正常的需求迭代。
第二次迭代歷程,經歷了第一次迭代后,新系統運行穩定,同時也具備接手新產品的能力,新工程開始與前端對接、聯調,在此之后,V2版本也正式上線。
模塊拆分
基于以往項目存在的問題,再結合消費分期的特點,我們對分期購買到賬單還款結清的整個流程進行拆解:用戶主動填寫申請信息,提交授信申請并獲額,挑選商品分期下單,生成還款計劃,提供綁卡、賬單還款等功能。以上就是一個簡單的分期購物流程,基于以上流程,我們把消費分期所包含的公共模塊,如授信前獲額、用信、賬單還款,這些富有金融服務屬性的功能進行剝離。消費分期作為轉轉的產品原型,在聚合層中各自維護,互不影響。
設計原則:在不改變原有代碼邏輯的情況下,根據單一職責和依賴倒置原則的思想:對系統進行模塊拆分與合并,以明確項目職責降低耦合度;對包進行重新規劃,劃分包與包之間的邊界,進一步減少代碼間的耦合。
好的代碼重構一定離不開設計模式,基于原有單一的策略模式,我們把合作方對接模塊與基礎服務模塊進行了拆解,采用雙層模板、策略、工廠模式的組合,分別對授信、用信、貸后幾個模塊單獨設計接口,維護好對合作方通用標準API接口,同時具備靈活接入的特點,舉個例子,以下為授信模塊主要代碼類圖:
第一層作為基礎服務的策略模式;
第二層作為合作方對接的策略模式。
主要類圖設計:
在定義接口與實現類后,形成了對合作方對接層依賴,同時對訂單、用信、授信等核心數據進行落地,對消費分期提供數據支撐,舉個例子,以下為授信模塊主要代碼:
/** * 授信接口定義 **/public interface ICreditService { /** * appId,資方定義的一個唯一ID */ String getAppId(); /** * app名稱 * * @return zz or zlj */ String getAppName(); /** * 獲取授信結果 * * @return result */ CreditResult creditResult(String logStr, Long uid);}
/** * 標準API對接實現 * **/public abstract class AbstractCreditService implements ICreditService { /** * 標準API對接 * * @return IBaseApiService */ protected abstract IBaseApiService getApiThirdService(); @Override public AppConfig getPartner() { return commonConfigUtil.getAppConfig(getAppId()); } @Override public CreditResult creditResult(String logStr, Long uid) { CreditResultInput input = new CreditResultInput(); input.setUid(uid); ResponseProtocol<CreditResultOutput> output = getApiThirdService().creditResult(logStr, input); String creditStatus = TransformUtil.approvalStatusTransform(output.getData()); return CreditResult.builder().result(creditStatus).build(); }}/** * 合作方差異化接入 */@Service@Slf4jpublic class ZZABCCreditServiceImpl extends AbstractABCCreditService { @Resource ZZABCThirdServiceImpl abcThirdService; @Override public String getAppId() { return PartnerEnum.ABC_ZZ_API.getAppId(); } @Override public String getAppName() { return AppNameEnum.ZZ.getValue(); } @Override protected IABCThirdService getABCThirdService() { return abcThirdService; }}
/** * 標準API對接 * * @author Rouse * @date 2022/4/24 13:57 */public interface IBaseApiService { /** * 標準API,獲取appId * * @return appId */ String getAppId(); /** * 獲取授信結果 */ ResponseProtocol<CreditResultOutput> creditResult(CreditResultInput input);}
/** * 合作方,標準API對接實現 * * @author Rouse * @date 2022/4/24 14:04 */@Slf4jpublic abstract class AbstractBaseApiService implements IBaseApiService { @Override public ResponseProtocol<CreditResultOutput> creditResult(CreditResultInput input) { // 通用加解密 return getDataResponse(logStr, getAppConf().getUrl4CreditResult(), input, CreditResultOutput.class); }}
/** * ABC合作方接口封裝 **/public interface IABCThirdService extends IBaseApiService { /** * 標準API,獲取appId * * @return appId */ String getAppId(); /** * 獲取授信結果 */ ResponseProtocol<ABCCreditResultOutput> creditResult(ABCCreditResultInput input);}/** * 合作方抽象方法封裝 **/@Slf4jpublic abstract class AbstractABCThirdService extends AbstractBaseApiService implements IABCThirdService { @Override public ResponseProtocol<ABCCreditResultOutput> creditResult(ABCCreditResultInput input) { // 加解密差異化實現 return getDataResponse(logStr, getAppConf().getUrl4CreditResult(), input, ABCCreditResultOutput.class); }}/** * ABC合作方對接 * */@Service@Slf4jpublic class ZZABCThirdServiceImpl extends AbstractABCThirdService{ @Override public String getAppId() { return PartnerEnum.ABC_API_ZZ.getAppId(); } @Override public String getAppName() { return AppNameEnum.ZZ.getValue(); }}
對于老系統的重構,新系統上線過度期也至關重要,因為采用了新的表結構進行重新設計,涉及到數據的同步,我們采用單向數據同步,逐漸棄用老系統數據,如果灰度期間需要回滾,首先對數據進行回滾,優先保證線上服務穩定。
以下是經歷兩次重構迭代的過程:
通過此次技術重構,我們不僅解決了過去存在的技術債務問題,還提升了服務的穩定性和用戶體驗,也提升產品交付效率。
技術重構并非一蹴而就,但只要我們有堅定的信念和不懈的努力,終將取得成功。引用一句名言:”不要因為懶惰而拒絕重構,不要因為無暇重構而成為你拖延的理由 。” 是的,重構是持續優化代碼質量和可維護性的過程,需要我們時刻關注并付諸行動。
我認為,重構的另一種價值:一個重構好的系統、往往具備通用性,可移植性。簡單說就是我們重構后的系統以最小的改動且能在同行中快速復用,因為你創造了一個穩定可靠的“輪子”,如果做到這點,無非你是這個行業技術解決方案的專家。
羅思,金融技術部后端研發工程師。轉轉消費分期業務開發。
本文鏈接:http://www.www897cc.com/showinfo-26-78505-0.html公司新來一個架構師, 將消費金融系統重構了
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com