首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

信貸業務領域建模與代碼重構:從 if-else 鏈到枚舉策略模式的演進

     編輯:Java 綜合教學

一、信貸業務雙視角領域模型

信貸系統天然存在兩個核心視角,對應兩條業務主線:

視角關注點領域對象核心流程
借款人視角 額度、利率、還款計劃 賬單、合同、還款記錄 申請 → 審批 → 放款 → 還款 → 結清
出資機構視角 風險敞口、收益率、資產質量 資產包、對接配置、風控策略 掛牌 → 分派 → 回款 → 核對 → 分配

領域模型上嚴格劃分:個人端 → 賬單域;機構端 → 資產域。機構對接採用「多一個機構、多一種類型對接」的插件化架構,實現 賬單 → 機構資產 → 機構對接 的單向依賴。

二、一達通·流水貸業務流程

面向使用一達通出口基礎服務的客戶,以出口額度積累授信額度的無抵押、免擔保、純信用貸款服務。由多家銀行聯合推出,核心流程:

  1. 客戶授權出口數據查詢
  2. 系統自動計算授信額度
  3. 多銀行競價匹配最優利率
  4. 電子簽約、實時放款
  5. 出口收匯自動還款閉環

三、代碼異味:基於類型的 if-else 鏈

// 原始代碼:枚舉值轉換散落在工具類
public static CreditSource convertCreditSource(Short quotaSource) {
    if (quotaSource == null) return null;
    if (StringUtils.equals(QuotaSourceEnum.CMBSX.getValue(), quotaSource.toString()))
        return CreditSource.bank_cmb;
    if (StringUtils.equals(QuotaSourceEnum.SUNSHINESX.getValue(), quotaSource.toString()))
        return CreditSource.ecreditbao_sun;
    // ... 8 個 if 分支
    return null;
}

問題:開閉原則違背,新增來源需修改工具類;字符串比較重複,易出錯;職責不清,轉換邏輯本屬於枚舉自身。

四、重構演進:三種方案對比

方案 A:枚舉內攜帶目標值(推薦)

public enum QuotaSourceEnum {
    BZJSX("1", null),
    INSTANT_HYSX("2", null),
    CMBSX("6", CreditSource.bank_cmb),      // 直接攜帶目標枚舉
    SUNSHINESX("7", CreditSource.ecreditbao_sun),
    // ... 其他
    private final String value;
    private final CreditSource creditSource;
    QuotaSourceEnum(String value, CreditSource creditSource) {
        this.value = value; this.creditSource = creditSource;
    }
    public static CreditSource parse(String value) {
        return Arrays.stream(values())
            .filter(e -> e.value.equals(value))
            .findFirst()
            .map(e -> e.creditSource)
            .orElse(null);
    }
}

// 調用極簡
public static CreditSource convertCreditSource(Short quotaSource) {
    return quotaSource == null ? null : QuotaSourceEnum.parse(quotaSource.toString());
}

優點:單一職責、零 if-else、新增來源只改枚舉。

方案 B:靜態 Map 緩存(高性能場景)

private static final Map MAP = new HashMap<>();
static {
    for (QuotaSourceEnum e : QuotaSourceEnum.values())
        if (e.creditSource != null) MAP.put(e.value, e.creditSource);
}
public static CreditSource convert(Short s) {
    return s == null ? null : MAP.get(s.toString());
}

優點:O(1) 查找,適合高頻調用;缺點:需維護靜態初始化塊。

方案 C:策略模式(行為差異大時)

若不同來源涉及複雜業務邏輯差異(如風控規則、利率計算),定義 CreditSourceStrategy 接口,枚舉持有策略實例,實現行為與數據封裝。

五、字符串比較規範化

// 統一使用工具類,避免 NPE 與大小寫陷阱
StringUtils.equals(str1, str2);             // null-safe 精確比較
StringUtils.equalsIgnoreCase(str1, str2);   // null-safe 忽略大小寫

六、枚舉即類:內聚相關邏輯

《Effective Java》建議用枚舉實現單例,同理:與枚舉值強相關的轉換、校驗、格式化邏輯應內置於枚舉內部,而非散落在外部 Utils 中。這樣:

  • 新增枚舉值時,IDE 提醒補全抽象方法,編譯期保證完整性。
  • 調用方無需感知內部映射細節,依賴倒置。
  • 單元測試可直接針對枚舉方法,測試覆蓋率更高。

總結

從「信貸雙視角建模」到「枚舉策略重構」,核心思想一致:將變化點封裝為穩定抽象。業務端劃分賬單/資產域隔離變化;代碼端用枚舉/策略封裝類型轉換邏輯。這才是領域驅動設計在工程落地的真諦。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved