簡介
介面卡模式 將一個類的介面,轉換成客戶期望的另一個介面。介面卡讓原本介面不相容的類可以合作無間
存在兩種介面卡: “物件介面卡” 和 “類”介面卡 (因為大部分語言不支援多重繼承,所以此處指的是物件介面卡)
介面卡模式包含一下三個角色:
1:Target(目標抽象類):目標抽象類定義客戶所需的介面,可以是一個抽象類或介面,也可以是具體類。在類介面卡中,由於java、php語言不支援多重繼承,所以它只能是介面。
2:Adapter(介面卡類):它可以呼叫另一個介面,作為一個轉換器,對Adaptee和Target進行適配。它是介面卡模式的核心。
3:Adaptee(適配者類):適配者即被適配的角色,它定義了一個已經存在的介面,這個介面需要適配,適配者類包好了客戶希望的業務方法。
圖例:
場景設定
系統已經在之前實現了訂單服務,在一個類裡面實現的(坑爹的萬能類),這個程式碼很複雜你們不想再冒風險去改動,並且有外部相關服務正在持續使用它。
就在這個時候,欠扁的產品給你提了一個需求,要你針對我們的後臺改造下某個共用的介面,在這個基礎上增加些欄位,比如下單人的姓名.
我們用簡單的介面卡模式實現下
程式碼實現
Order.php 相當於Adaptee需要適配的類
<?php
class Order
{
/**
* 根據訂單號查詢資訊
*
* @param $orderNo
* @return array
*/
public function getInfoByOrderNo($orderNo)
{
//todo 資料資源操作
return [
'order' => [
'orderId' => '2018050320423042',
'title' => '冬天大棉襖',
'price' => '68000',
],
];
}
}
複製程式碼
客戶期望實現的介面類
<?php
interface OrderBackstage
{
public function getUserOrderByOrderNo(int $orderNo): string;
}
複製程式碼
OrderAdepter 適配類(把源介面轉換成目標介面)
<?php
class OrderAdepter implements OrderBackstage
{
private $orderService = null;
public function __construct()
{
$this->orderService = new Order();
}
/**
* 根據訂單號獲取使用者userid
*/
public function getUserOrderByOrderNo(int $orderNo): string
{
$order = $this->orderService->getInfoByOrderNo($orderNo);
if (!empty($order)) {
//todo 其它查詢拼裝
$order['user'] = [
'uid' => 24,
'name' => '小明',
'avatar' => 'http://xxx.com/xx.png'
];
} else {
$order = [];
}
return json_encode($order);
}
}
複製程式碼
呼叫:
$order = new OrderAdepter();
$result = $order->getUserOrderByOrderNo(123);
echo $result;
複製程式碼
output:
{"order":{"orderId":"2018050320423042","title":"\u51ac\u5929\u5927\u68c9\u8884","price":"68000"},"user":{"uid":24,"name":"\u5c0f\u660e","avatar":"http:\/\/xxx.com\/xx.png"}}
複製程式碼
具體UML圖:
總結
介面卡模式比較簡單,程式碼均採用php語言實現。
介面卡模式主要應用於希望複用一些現存的類,但是介面要求又與複用環境要求不一致的情況。
兩個類所做的事情相同或相似,但是具有不同的業務或介面使用時(比如對後臺提供介面,可展示一些敏感電話資訊,但對外就需要過濾掉)
使用介面卡可最小化的影響舊有的業務系統,來增加新的功能。
通過介面卡模式,我們下次可以看看外觀模式究竟和有什麼區別..
更多精彩內容,關注微信公眾號: