設計緣由
因爲服務愈來愈小型化或者分工愈來愈精細,這樣的場景愈來愈多見:架構
須要從多個不一樣的服務(SOA服務、Restful服務)獲取數據,截取其中一部分返回進行進一步處理,生成自身領域模型須要的業務數據併發
乍看其實很簡單,就是獲取數據——MAP映射數據——對映射數據執行領域業務邏輯app
但實際狀況可能複雜的多性能
獲取數據
- 獲取數據的時候,數據源不一致,對每種數據源要進行封裝
- 數據源獲取的時候,每一項業務可能獲取的數據源不一致
- 獲取的數據源可能互相依賴,好比B數據源的Request須要A數據源的Response
- 獲取數據源無互相依賴,爲了性能,可能須要併發獲取,或者對每種數據源進行設置超時(可能某些數據源自帶超時或熔斷功能,有些沒有,又須要本身實現)
單看以上每種問題都比較好解決,可是這些問題混合在一塊兒的時候就很頭大了線程
MAP映射數據
- 對同一種數據源,MAP的粗細程度可能不同,有些須要精細Map,有些只須要簡易的Map
- Map代碼可能散落在代碼庫各處,不方便以後維護的人閱讀,後來的人改起來吃力,可能就本身重寫了,致使有多種重複Map
因此萌發了寫一套代碼能通吃處理以上問題設計
目的是能:對象
- 最大限度重用數據源調用
- 最大限度重用數據映射邏輯
- 靈活的數據獲取和映射
- 新建立數據源、數據映射能夠方便集成進現有架構
- 業務變化,某些映射邏輯過期後,能夠只需在一處修改(映射代碼只會出現一次)
原理模型
RequestEntity封裝請求類,容納全部DataSource請求所須要的字段(能夠是巨型實體)it
ResponseEntity封裝返回類,容納全部Mapper映射後的返回字段(能夠是巨型實體)泛型
使用方法原理
- 首先實例化DataSource的子類,一個子類表明一種數據來源
- 建立Mapper對象,因爲有TResponse協變泛型進行約束,保證數據源只有能處理的Mapper進行處理
- 將Mapper加入數據源MapperList
- FetchData從第三方數據源獲取數據
- GetResponse遍歷全部Mapper進行第三方數據到ResponseEntity的映射
- 若是須要從別的數據源獲取,能夠直接重複1-5的操做,ResponseEntity做爲已經處理過的數據,能夠參與到後續的映射中
- 若是須要併發獲取,能夠單獨寫方法建立多個線程同時執行多數據源的Fetch操做
代碼實現
參考火車票動態答案項目、zhixingflight動態答案項目
改進方向
MapperList也能夠影響DataSource的RequestEntity
因爲大量使用組合的方式,去除耦合,致使有可能須要將Mapper切分的很細,具體仍是須要使用的人來決定是否切分Mapper