如何設計投放系統系列—-靈活的欄位對映補全機制
引言
我們知道搭建系統跟投放系統是兩個緊密關聯的系統,搭建產出的是頁面的結構,投放產出的是頁面的資料。搭建產出的頁面包含各式各樣的模組,這些模組包含的欄位也沒有太多規律可言,那麼投放系統怎麼為這些模組補全資料呢?
在回答這個問題之前,我們先嚐試解決一些簡單的業務 case
。
幾個案例
案例一
有一個商品模組,欄位包括:商品的標題、商品圖片、購買連結、商品價格、商品描述,想要投放某個選品集的商品,請問投放系統應該怎麼設計以補全這些欄位資訊?
拿到這個需求,最直觀的解決方案就是,直接去商品庫取選品集對應的商品列表,把商品庫裡的欄位塞到對應的模組欄位上。
// 商品選品集
var goodSet = [1,2,3,4,5];
// 從商品庫獲取對應的商品實體資訊
var entityMap = goodService.fetch(goodSet);
var output = [];
for (var i = 0, l = goodSet.length; i < l; ++i) {
var goodId = goodSet[i];
var entity = entityMap[goodId];
if (!entity) {
continue;
}
// 欄位對映
output.push({
`商品名稱`: entity[`goodName`],
`商品圖片`: entity[`goodImg`],
`商品連結`: entity[`goodLink`],
`商品價格`: entity[`goodPrice`]
...
});
}
return output;
案例二
有一個店鋪模組,欄位包括:店鋪的名稱、店鋪的照片、店鋪連結,想要投放某個選品集的店鋪列表,請問投放系統應該怎麼設計以補全這些欄位資訊?
這個需求跟上面一個類似,依然是最直觀的解決方案,直接去店鋪庫取選品集對應的店鋪列表,把店鋪庫裡的欄位塞到對應的模組欄位上。
// 店鋪選品集
var shopSet = [1,2,3,4,5];
// 從店鋪庫獲取對應的店鋪實體資訊
var entityMap = shopService.fetch(shopSet);
var output = [];
for (var i = 0, l = shopSet.length; i < l; ++i) {
var shopId = shopSet[i];
var entity = entityMap[shopId];
if (!entity) {
continue;
}
// 欄位對映
output.push({
`店鋪名稱`: entity[`shopName`],
`店鋪圖片`: entity[`shopImg`],
`店鋪連結`: entity[`shopLink`]
});
}
return output;
案例三
同樣一個商品模組,欄位包括:商品的標題、商品圖片、購買連結、商品價格、優惠價格,想要投放某個選品集的商品,請問投放系統應該怎麼設計以補全這些欄位資訊?
這個 case 我們發現單純的從商品庫取不到優惠價格資訊,必須去另外一個服務獲取商品的優惠價格。
對應的虛擬碼為:
// 商品選品集
var goodSet = [1,2,3,4,5];
// 從商品庫獲取對應的商品實體資訊
var entityMap = goodService.fetch(goodSet);
var output = [];
for (var i = 0, l = goodSet.length; i < l; ++i) {
var goodId = goodSet[i];
var entity = entityMap[goodId];
if (!entity) {
continue;
}
// 欄位對映
output.push({
`商品名稱`: entity[`goodName`],
`商品圖片`: entity[`goodImg`],
`商品連結`: entity[`goodLink`],
`商品價格`: entity[`goodPrice`],
// 去優惠券服務獲取商品的優惠價格
`優惠價格`: couponService.fetch(goodId).price
});
}
return output;
到了這裡,我們發現模組只要一變,程式碼就得跟著變,有沒有辦法能模組變化,程式碼不變呢?
終極解決方案
相信聰明的你已經可以看出,隨著需求的變化,我們的程式碼變化的都是欄位的補全來源以及欄位的對映關係,不變的是整個程式碼的流程。如果我們可以把這些變化的部分做成可配置的,似乎程式碼就不需要變動了。
我們試著寫了這樣一個介面
function get(id, field);
這個介面只需要傳實體的 id
,以及需要返回的欄位名,就可以返回對應的值。
每個欄位的具體補全邏輯都是 get
的具體實現,我們把實現做成可配置的形式
商品資料來源配置
{
`goodName`: {adapter: `goodService`, param: [`id`, `goodName`]},
`goodPrice`: {adapter: `goodService`, param: [`id`, `goodPrice`]}
`couponPrice`: {adapter: `couponService`, param: [`id`, `couponPrice`]}
}
店鋪資料來源配置
{
`shopName`: {adapter: `shopService`, param: [`id`, `shopName`]},
`shopImg`: {adapter: `shopService`, param: [`id`, `shopImg`]}
}
接著我們再新增一些配置,配置的是模組素材欄位跟資料來源中的欄位ID的對映關係。
商品欄位對映
模組素材欄位編碼 => 資料來源欄位 ID
{
`商品名稱`: `goodName`,
`商品圖片`: `goodImg`,
`商品連結`: `goodLink`,
`商品價格`: `goodPrice`,
`優惠價格`: `couponPrice`
}
店鋪欄位對映
{
`店鋪名稱`: `shopName`,
`店鋪圖片`: `shopImg`,
`店鋪連結`: `shopLink`
}
最後我們再修改下虛擬碼:
function get(id, field) {
var param = configService.getDatastoreConfig(field).param;
return adapterFactory.get(field).apply(param);
}
// 選品集
var entitySet = [1,2,3,4,5];
// 實體型別
var entityType = model.entityType;
// 獲取欄位對映配置
var fieldMappingConfig = configService.getFieldMappingConfig(entityType);
var output = [];
for (var i = 0, l = entitySet.length; i < l; ++i) {
var entityId = entitySet[i];
var entity = {id: entityId};
// 遍歷模組的欄位列表
for (var j = 0; j < model.fields.length; ++j) {
// 模組欄位編碼
var field = model.fields[j];
// 補全該欄位的值,get 會用資料來源配置的類和引數補全該欄位的值
entity[field] = get(entityId, fieldMappingConfig[field]);
}
output.push(entity);
}
return output;
上面其實也是我們 UTCP
系統目前的設計思路。
get
get
介面對應的就是 AbstractEntity.get
方法。
欄位對映配置
資料來源配置
相關文章
- JPA實體中欄位對映補充和嵌入物件物件
- 巧用欄位對映實現指定欄位的搜尋
- 裝備屬性欄位設計和投放詳解
- oracle時間欄位預設值,hibernate對映Oracle
- 【Mybatis系列】從原始碼角度理解Mybatis欄位對映-AS&ResultMapMyBatis原始碼
- JPA關係對映系列五:many-to-many 關聯表存在額外欄位關係對映
- Mybatis處理列名—欄位名對映— 駝峰式命名對映MyBatis
- 將多個JSON欄位對映到單個Java欄位JSONJava
- 揭秘!閒魚拉新投放系統如何設計
- 【Mybatis系列】從原始碼角度理解Mybatis欄位對映-駝峰式命名MyBatis原始碼
- [譯]Swift: 利用 Enum 靈活對映多重型別 Data modelSwift型別
- resultMap 和 resultType 的欄位對映覆蓋問題
- laravel使用save與update方法靈活操作updated_at欄位Laravel
- 靈活的查詢設計方案
- 如何通過模組/外掛機制,靈活組織Laravel工程Laravel
- 如何透過模組/外掛機制,靈活組織Laravel工程Laravel
- 超硬核解析!Apache Hudi靈活的Payload機制Apache
- Hibernate對檢視對映,當檢視中有空欄位的時候如何解決?
- OFFICE2K符號欄的靈活設定 (轉)符號
- windows域控裡,屬性和欄位對映表Windows
- mybatis 實體類排除資料庫欄位對映MyBatis資料庫
- 計算機系統的安全機制計算機
- 二進位制檔案記憶體對映記憶體
- [案例] 字元型欄位統計資訊只對前32位進行統計字元
- 讀懂框架設計的靈魂—Java反射機制框架Java反射
- 彭民德:《電子計算60年》(15) 作業系統造就計算機活的靈魂作業系統計算機
- MFC 訊息對映機制詳解
- 計算機二進位制中的原碼,反碼,補碼計算機
- 模型驅動設計(MDD)之靈活設計模型
- Windows是如何將64位Ntdll對映到32位程式的Windows
- Ubuntu系統 git命令補全UbuntuGit
- [計算機基礎] 計算機進位制轉換:二進位制、八進位制、十進位制、十六進位制計算機
- ThinkPHP3.2.3 欄位對映/自動驗證/自動完成PHP
- 高可用高可靠系統設計中的重試機制
- 移動端支付系統如何設計有效地防重失效機制?
- LeetCode 642 號問題:設計搜尋自動補全系統LeetCode
- Java設計模式——觀察者模式的靈活應用Java設計模式
- [MySQLFAQ]系列–快速對調欄位裡面的某些列MySql