最近遇到一個場景的問題:多個系統共用同一個枚舉時的維護問題。在網上,按照關鍵詞:從 枚舉 到 數據字典 ,一路搜索過去,遇到幾篇不錯的文章。整理一下,相似於作個綜述。java
從 問題 以及 直觀的解決方案 來表述問題的演變過程:編程
1. 在DB設計中,某個字段的取值範圍只會是 某幾種值,好比性別只會取:男 or 女,咱們若是想在後續校驗這個字段的值是是否規範要求的怎麼辦? 單獨拎一張類型表出來,在這張表中就設定這個type只能是某幾種value,後續在代碼中拿這張表的數據做爲參考往業務表中插值。這種解決方案,咱們通常稱之爲 [類別表]。 2. 在作後臺管理系統開發時,常常會遇到不少下拉select選項,這些下拉select的值通常是固定的幾個,若是按照上面的思路,咱們要建不少 [類別表]。不想建不少類別表,怎麼辦? 作一張公共的類別表,這張表裏面存按照code區分不一樣類別。這種解決方案,咱們通常稱之爲 [數據字典表]. 通常咱們還會在後臺系統中設計一個 數據字典菜單功能,方便修改字典。 3. 在java代碼系統(或強類型語言)中,咱們要從DB中讀取數據字典放到內存中,否則每次都就去DB中作查詢,多浪費性能啊。可是放到內存中,咱們用什麼類型來存放呢? Map or Enum,咱們通常會用上面這兩種類型。請注意這裏都是從DB -> java對象,好比拿枚舉來講,若是作要作任何的 值的比較是無法作的,由於一開始enum多是一個空的enum而後讀取DB動態加載了枚舉項,因此是無法直接拿枚舉的字面項去使用。 作判斷必須是 字符串 轉 枚舉,而後枚舉和枚舉之間的比較;又或者是 枚舉 轉 字符串,字符串和字符串之間作比較。 4. 若是一個公司有不少系統,由於要作數據標準化,因此必須限定都是用同一套數據字典,並且爲了編程的便利性,咱們要求直接將 DB數據字典 加載爲 java內存裏的enum,這時怎麼處理呢? 這時能夠是一個公共二方包sdk來作這件事兒,仍是每一個系統均可以本身獨立加載。每一個系統在啓動時都經過公共SDK,來動態刷新二方包中定義的枚舉項。 這樣限定了整個公司的全部系統不只要 數據字典的值要一致,並且用到的枚舉值也必須一致。 5. 若是後續某個字典項的值修改了,是否要通知到全部依賴SDK包的下游系統作聯動發佈呢? 這個問題,也是分佈式系統建設中,如何創建並維護一個公共配置中心的問題同樣相似的思路,若是數據字典的值在DB中作了修改那麼能夠經過kafka等異步消息的方式通知到全部下游系統中去。下游系統consume到消息時作枚舉的動態加載操做。
上面幾個解決方案之外的思考:緩存
1. 不能直接利用枚舉的字面值進行比較是個限制。 且java的枚舉這種數據結構類型的語義是,靜態的、固定的、不易修改的一類數據。因此,在有些文章上會說,動態加載枚舉項是破壞了代碼的可讀性。 2. 版本的考慮,數據字典的數據應當是不能updae,不能delete,只能insert的。由於歷史數據中已經使用了以前的枚舉項。 3. 爲何不直接用數據字典緩存SDK包呢?想的是,經過枚舉仍是能起到一些強類型語言的優點。
比較不錯的幾篇文章:
1. http://www.talkwithtrend.com/Article/220231數據結構
這篇文章比較宏觀,從公司的數據標準化建設的角度,來談這個問題。解決方案可總結爲,基於配置中心作本地可熱加載的查詢緩存系統。異步
2. https://blog.claves.me/2019/03/12/dict_enum/分佈式
https://blog.csdn.net/weixin_42476601/article/details/84261992性能
介紹了數據字典的概念,枚舉的概念。spa
3. https://blog.csdn.net/qq_35530330/article/details/85647826.net
介紹了動態加載java枚舉項的方法。設計