信貸系統天然存在兩個核心視角,對應兩條業務主線:
| 視角 | 關注點 | 領域對象 | 核心流程 |
|---|---|---|---|
| 借款人視角 | 額度、利率、還款計劃 | 賬單、合同、還款記錄 | 申請 → 審批 → 放款 → 還款 → 結清 |
| 出資機構視角 | 風險敞口、收益率、資產質量 | 資產包、對接配置、風控策略 | 掛牌 → 分派 → 回款 → 核對 → 分配 |
領域模型上嚴格劃分:個人端 → 賬單域;機構端 → 資產域。機構對接採用「多一個機構、多一種類型對接」的插件化架構,實現 賬單 → 機構資產 → 機構對接 的單向依賴。
面向使用一達通出口基礎服務的客戶,以出口額度積累授信額度的無抵押、免擔保、純信用貸款服務。由多家銀行聯合推出,核心流程:
// 原始代碼:枚舉值轉換散落在工具類
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;
}
問題:開閉原則違背,新增來源需修改工具類;字符串比較重複,易出錯;職責不清,轉換邏輯本屬於枚舉自身。
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、新增來源只改枚舉。
private static final MapMAP = 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) 查找,適合高頻調用;缺點:需維護靜態初始化塊。
若不同來源涉及複雜業務邏輯差異(如風控規則、利率計算),定義 CreditSourceStrategy 接口,枚舉持有策略實例,實現行為與數據封裝。
// 統一使用工具類,避免 NPE 與大小寫陷阱 StringUtils.equals(str1, str2); // null-safe 精確比較 StringUtils.equalsIgnoreCase(str1, str2); // null-safe 忽略大小寫
《Effective Java》建議用枚舉實現單例,同理:與枚舉值強相關的轉換、校驗、格式化邏輯應內置於枚舉內部,而非散落在外部 Utils 中。這樣:
從「信貸雙視角建模」到「枚舉策略重構」,核心思想一致:將變化點封裝為穩定抽象。業務端劃分賬單/資產域隔離變化;代碼端用枚舉/策略封裝類型轉換邏輯。這才是領域驅動設計在工程落地的真諦。