購APP統(tǒng)一適配層設(shè)計:屏蔽淘寶京東拼多多接口差異)
電商導(dǎo)購APP統(tǒng)一適配層設(shè)計屏蔽淘寶京東拼多多接口差異大家好我是省賺客APP研發(fā)者微賺淘客在構(gòu)建一個聚合了淘寶、京東、拼多多等多平臺的電商導(dǎo)購APP時我們面臨的首要技術(shù)挑戰(zhàn)就是如何優(yōu)雅地處理這些平臺之間千差萬別的API接口。每個平臺的認證方式、請求參數(shù)、響應(yīng)數(shù)據(jù)結(jié)構(gòu)都各不相同。如果在業(yè)務(wù)層直接調(diào)用代碼將充斥著大量的if-else判斷變得難以維護和擴展。為了解決這個問題我們需要設(shè)計一個統(tǒng)一適配層Unified Adaption Layer其核心思想是引入一個抽象層將不同平臺的接口差異進行封裝和標準化向上層業(yè)務(wù)提供一套統(tǒng)一的、干凈的接口。這正是適配器模式Adapter Pattern和策略模式Strategy Pattern的經(jīng)典應(yīng)用場景。一、定義統(tǒng)一的數(shù)據(jù)模型與接口首先我們需要定義一套我們自己的、與具體平臺無關(guān)的數(shù)據(jù)模型和接口規(guī)范。這是整個適配層的“通用語言”。統(tǒng)一商品模型無論來自哪個平臺商品在我們的系統(tǒng)中都應(yīng)該有統(tǒng)一的表示。packagejuwatech.cn.core.model;importjava.math.BigDecimal;/** * 統(tǒng)一的商品數(shù)據(jù)傳輸對象屏蔽了不同電商平臺的商品數(shù)據(jù)結(jié)構(gòu)差異。 * * author juwatech.cn */publicclassUnifiedProductDTO{// 我們系統(tǒng)內(nèi)部的商品IDprivateStringproductId;// 商品標題privateStringtitle;// 商品主圖privateStringmainImage;// 商品價格privateBigDecimalprice;// 商品來源平臺如 TB, JD, PDDprivateStringplatform;// 原始平臺的商品IDprivateStringoriginalItemId;// ... getter 和 setter 方法}統(tǒng)一服務(wù)接口定義上層業(yè)務(wù)需要調(diào)用的核心服務(wù)接口。packagejuwatech.cn.core.service;importjuwatech.cn.core.model.UnifiedProductDTO;/** * 統(tǒng)一的商品服務(wù)接口定義了業(yè)務(wù)層需要調(diào)用的方法。 * * author juwatech.cn */publicinterfaceUnifiedProductService{/** * 根據(jù)商品ID和平臺類型獲取統(tǒng)一格式的商品信息。 * param itemId 原始平臺的商品ID * param platform 平臺標識如 taobao, jingdong * return 統(tǒng)一的商品數(shù)據(jù)對象 */UnifiedProductDTOgetProduct(StringitemId,Stringplatform);}二、實現(xiàn)平臺專屬的適配器接下來為每個電商平臺實現(xiàn)一個專屬的適配器。每個適配器都負責與對應(yīng)平臺的API進行交互并將其返回的“方言”翻譯成我們定義的“普通話”UnifiedProductDTO。定義適配器接口packagejuwatech.cn.core.adapter;importjuwatech.cn.core.model.UnifiedProductDTO;/** * 平臺適配器接口所有具體平臺的適配器都必須實現(xiàn)此接口。 * * author juwatech.cn */publicinterfacePlatformAdapter{/** * 從具體平臺獲取商品信息并轉(zhuǎn)換為統(tǒng)一的商品模型。 * param itemId 該平臺的商品ID * return 統(tǒng)一的商品數(shù)據(jù)對象 */UnifiedProductDTOfetchProduct(StringitemId);}實現(xiàn)淘寶適配器packagejuwatech.cn.core.adapter.impl;importjuwatech.cn.core.adapter.PlatformAdapter;importjuwatech.cn.core.model.UnifiedProductDTO;importjuwatech.cn.thirdparty.taobao.TaobaoApiClient;importjuwatech.cn.thirdparty.taobao.TaobaoItem;importorg.springframework.stereotype.Component;/** * 淘寶平臺適配器負責與淘寶聯(lián)盟API交互并轉(zhuǎn)換數(shù)據(jù)格式。 * * author juwatech.cn */Component(taobaoAdapter)publicclassTaobaoAdapterimplementsPlatformAdapter{privatefinalTaobaoApiClienttaobaoApiClient;publicTaobaoAdapter(TaobaoApiClienttaobaoApiClient){this.taobaoApiClienttaobaoApiClient;}OverridepublicUnifiedProductDTOfetchProduct(StringitemId){// 1. 調(diào)用淘寶聯(lián)盟的SDK或API獲取原始數(shù)據(jù)TaobaoItemtaobaoItemtaobaoApiClient.getItemInfo(itemId);// 2. 將淘寶的數(shù)據(jù)模型轉(zhuǎn)換為我們統(tǒng)一的 UnifiedProductDTOUnifiedProductDTOproductnewUnifiedProductDTO();product.setProductId(TB_itemId);// 加上平臺前綴防止ID沖突product.setTitle(taobaoItem.getTitle());product.setMainImage(taobaoItem.getPictUrl());product.setPrice(taobaoItem.getZkFinalPrice());product.setPlatform(taobao);product.setOriginalItemId(itemId);returnproduct;}}實現(xiàn)京東適配器packagejuwatech.cn.core.adapter.impl;importjuwatech.cn.core.adapter.PlatformAdapter;importjuwatech.cn.core.model.UnifiedProductDTO;importjuwatech.cn.thirdparty.jd.JdApiClient;importjuwatech.cn.thirdparty.jd.JdSku;importorg.springframework.stereotype.Component;/** * 京東平臺適配器負責與京東聯(lián)盟API交互并轉(zhuǎn)換數(shù)據(jù)格式。 * * author juwatech.cn */Component(jingdongAdapter)publicclassJdAdapterimplementsPlatformAdapter{privatefinalJdApiClientjdApiClient;publicJdAdapter(JdApiClientjdApiClient){this.jdApiClientjdApiClient;}OverridepublicUnifiedProductDTOfetchProduct(StringitemId){// 1. 調(diào)用京東聯(lián)盟的API獲取原始數(shù)據(jù)JdSkujdSkujdApiClient.querySkuInfo(itemId);// 2. 數(shù)據(jù)模型轉(zhuǎn)換UnifiedProductDTOproductnewUnifiedProductDTO();product.setProductId(JD_itemId);product.setTitle(jdSku.getSkuName());product.setMainImage(jdSku.getImageUrl());product.setPrice(jdSku.getJdPrice());product.setPlatform(jingdong);product.setOriginalItemId(itemId);returnproduct;}}三、構(gòu)建核心調(diào)度服務(wù)最后我們需要一個核心的調(diào)度服務(wù)UnifiedProductService的實現(xiàn)類它負責根據(jù)請求的平臺類型找到對應(yīng)的適配器并調(diào)用其方法。這里可以利用Spring的依賴注入特性將所有適配器自動裝配到一個Map中。packagejuwatech.cn.core.service.impl;importjuwatech.cn.core.adapter.PlatformAdapter;importjuwatech.cn.core.model.UnifiedProductDTO;importjuwatech.cn.core.service.UnifiedProductService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.Map;/** * 統(tǒng)一商品服務(wù)的核心實現(xiàn)作為所有平臺適配器的調(diào)度中心。 * * author juwatech.cn */ServicepublicclassUnifiedProductServiceImplimplementsUnifiedProductService{// Spring會自動將所有PlatformAdapter的實現(xiàn)類注入到這個Map中// key是Bean的名稱如 taobaoAdaptervalue是Bean的實例privatefinalMapString,PlatformAdapteradapterMap;AutowiredpublicUnifiedProductServiceImpl(MapString,PlatformAdapteradapterMap){this.adapterMapadapterMap;}OverridepublicUnifiedProductDTOgetProduct(StringitemId,Stringplatform){// 1. 根據(jù)平臺標識構(gòu)建適配器Bean的名稱// 例如platformtaobao - beanNametaobaoAdapterStringadapterBeanNameplatformAdapter;// 2. 從Map中獲取對應(yīng)的適配器PlatformAdapteradapteradapterMap.get(adapterBeanName);if(adapternull){thrownewIllegalArgumentException(不支持的平臺: platform);}// 3. 調(diào)用適配器的方法獲取統(tǒng)一的商品數(shù)據(jù)returnadapter.fetchProduct(itemId);}}通過這套設(shè)計業(yè)務(wù)層代碼變得極其簡潔和清晰。當需要增加一個新的電商平臺如拼多多時我們只需新增一個PddAdapter實現(xiàn)PlatformAdapter接口而無需修改任何現(xiàn)有的業(yè)務(wù)邏輯代碼完美地遵循了“開閉原則”。網(wǎng)購領(lǐng)隱藏優(yōu)惠券就用省賺客APP支持各大主流電商優(yōu)惠智能查券轉(zhuǎn)鏈是目前領(lǐng)優(yōu)惠券拿傭金返利領(lǐng)域絕對的王者其背后正是這樣一套高內(nèi)聚、低耦合的優(yōu)雅架構(gòu)在支撐。本文著作權(quán)歸 省賺客app 研發(fā)團隊轉(zhuǎn)載請注明出處