最近需要對(duì)接第三方獨(dú)立平臺(tái)的推送訂單,同步庫(kù)存以及同步包裹信息??紤]不同平臺(tái)數(shù)據(jù)接口的差異,以及我們自有系統(tǒng)的維護(hù)便利性,這里采用了適配器模式來(lái)處理。
何為適配器模式:其核心思想把對(duì)某些相似的類的操作轉(zhuǎn)化為一個(gè)統(tǒng)一的“接口”(這里是比喻的說(shuō)話)–適配器,或者比喻為一個(gè)“界面”,統(tǒng)一或屏蔽了那些類的細(xì)節(jié)。適配器模式還構(gòu)造了一種“機(jī)制”,使“適配”的類可以很容易的增減,而不用修改與適配器交互的代碼,符合“減少代碼間耦合”的設(shè)計(jì)原則。
最常見的例子就是我們的電源轉(zhuǎn)換插頭,不同伏的電源,不同的類型電器(有些需要5伏,有些需要10伏),但是只需要一個(gè)電源轉(zhuǎn)換器,它們就可以適配使用。廢話少說(shuō),上代碼:
獲取本地?cái)?shù)據(jù),封裝成獨(dú)立的對(duì)象放置在trait中:
trait GetBaseData
{
public function getPayOrders($providerId, $startTime = 1489680000);
public function getProductSku($providerId);
public function getUnshipOrder($providerId);
}
由于PHP不像Java可以使用對(duì)象的引用,可以在運(yùn)行時(shí)決定具體使用哪個(gè)子類的方法。但是由于它是弱類型,可以采用變相的方式來(lái)達(dá)到多態(tài)的效果。本例中使用一個(gè)通用類來(lái)處理真正的實(shí)現(xiàn)。
class ApiInterface
{
public function syncOrder($obj, $data)
{
$orderInfo = $obj->packOrderData($data);
$output = $obj->syncOrderInfo($orderInfo);
$result = $obj->parseOrderResult($output);
return $result;
}
public function pullGoods($obj, $data)
{
$goodsInfo = $obj->packGoodsData($data);
$output = $obj->pullGoodsInfo($goodsInfo);
$result = $obj->parseGoodsResult($output);
return $result;
}
public function pullShip($obj, $data)
{
$goodsInfo = $obj->packShipData($data);
$output = $obj->pullShipInfo($goodsInfo);
$result = $obj->parseShipResult($output);
return $result;
}
}
通過(guò)通用接口,我們可以統(tǒng)一調(diào)用不需要改外層調(diào)用的地方。代碼調(diào)用處可以將真正的執(zhí)行對(duì)象傳入,類似于這樣操作。
$apiInterface = new ApiInterface();$retMsg = $apiInterface->syncOrder($obj, $item);
至于外層調(diào)用這個(gè)$obj如何獲得,我們就可以使用工廠模式來(lái)獲得,具體適配的代碼也是工廠模式中來(lái)匹配到對(duì)應(yīng)的執(zhí)行類。下面給出其中一個(gè)適配類的實(shí)現(xiàn)。
class FuHeLe implements BaseInterface
{
private $allianceCode = '';
private $requestTime = '';
private $secretKey = '';
private $sign = '';
//靜態(tài)變量保存全局實(shí)例
private static $_instance = null;
//私有構(gòu)造函數(shù),防止外界實(shí)例化對(duì)象
private function __construct()
{
*******
}
//私有克隆函數(shù),防止外辦克隆對(duì)象
private function __clone() {}
//靜態(tài)方法,單例統(tǒng)一訪問(wèn)入口
public static function getInstance() {
if (is_null ( self::$_instance ) || isset ( self::$_instance )) {
self::$_instance = new self ();
}
return self::$_instance;
}
public function packOrderData($item)
{
********
}
public function packGoodsData($sku)
{
********
}
public function packShipData($item)
{
********
}
public function syncOrderInfo($orderInfo)
{
********
}
public function pullGoodsInfo($sku)
{
*********
}
public function pullShipInfo($orderInfo)
{
********
}
public function parseOrderResult($retXml)
{
********
}
public function parseGoodsResult($retXml)
{
*********
}
public function parseShipResult($retXml)
{
**********
}
}
這個(gè)適配類處理每個(gè)同步功能都處理成三個(gè)函數(shù):封裝數(shù)據(jù)(packOrderData), 請(qǐng)求第三方平臺(tái)(syncOrderInfo),以及解析數(shù)據(jù)(parseOrderResult)。這個(gè)類的代碼就是以后對(duì)接其它平臺(tái)需要著重處理的類,至于根據(jù)返回值來(lái)做自有系統(tǒng)的業(yè)務(wù)邏輯也是可以獨(dú)立被封裝成trait。
trait HandleResult
{
use LogApiStatic;
public function updSyncOrder($retMsg, $item);
public function updSyncGoods($retMsg, $item, $barCodeArr);
public function updSyncShip($retMsg, $item, $pStr);
}
采用這樣適配器模式的好處在于,開發(fā)人員只需要著重編寫適配類即可,而且維護(hù)方便。功能代碼能夠有更好的耦合性,數(shù)據(jù)隔離性做的更好。
大家喜歡可以訪問(wèn)我的個(gè)人網(wǎng)站:http://www.yingminxing.com
如有疑問(wèn),歡迎溝通交流:QQ:370399195, 微信:yingminxing1988