設計模式
- 【設計模式】工廠方法模式
- 【設計模式】抽象工廠模式
- 【設計模式】單例模式
- 【設計模式】策略模式
- 【設計模式】觀察者模式
- 【設計模式】裝飾模式
- 【設計模式】介面卡模式
一、介紹
介面卡模式是一種結構型設計模式, 它能使介面不相容的物件能夠相互合作。
介面卡可擔任兩個物件間的封裝器,它會接收對於一個物件的呼叫,並將其轉換為另一個物件可識別的格式和介面。
介面卡模式在 PHP 程式碼中很常見。 基於一些遺留程式碼的系統常常會使用該模式。 在這種情況下, 介面卡讓遺留程式碼與現代的類得以相互合作。
應用場景:
(1)當你希望使用某個類,但是其介面與其他程式碼不相容時,可以使用介面卡類。
(2)如果您需要複用一些類,他們處於同一個繼承體系,並且他們又有了額外的一些共同的方法,但是這些共同的方法不是所有在這一繼承體系中的子類所具有的共性。
二、優缺點
優點:
- 單一職責原則:你可以將介面或資料轉換程式碼從程式主要業務邏輯中分離。
- 開閉原則:只要客戶端程式碼透過客戶端介面與介面卡進行互動, 你就能在不修改現有客戶端程式碼的情況下在程式中新增新型別的介面卡。
缺點:
- 程式碼整體複雜度增加,因為需要新增一系列介面和類。
三、核心結構
Adapter(介面卡):最主要的就是這個介面卡類,用於適配、擴充套件功能或介面。
四、程式碼實現
1、應用場景1
當你希望使用某個類,但是其介面與其他程式碼不相容時,可以使用介面卡類。
例如:有一臺電腦顯示器本身是VGA的資料線,但現在你手裡只有HDMI的資料線,這個時候只有有個介面卡(轉接頭)就可以使用。
(1)LcdInterface類本身相當於電腦螢幕,vga()方法相當於電腦螢幕自帶的vga格式的介面
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/8/1 * Time: 15:47 */ namespace app\admin\service\mode\adapter\other; /** * LcdInterface介面類本身相當於電腦螢幕 * vga()方法相當於電腦螢幕自帶的vga格式的介面 */ interface LcdInterface { public function vga(); }
(2)介面卡(轉接頭)
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/8/1 * Time: 15:54 */ namespace app\admin\service\mode\adapter\other; /** * 介面卡(轉接頭) */ class Adapter implements LcdInterface { private NewDataCable $chinaPlug; public function __construct(NewDataCable $chinaPlug) { $this->chinaPlug = $chinaPlug; } /** * 使用介面卡,將HDMI介面轉換為VGA格式 * 相當於顯示器還是使用VGA介面,但是透過介面卡,將HDMI介面轉換為VGA介面 * @return void * @Author: fengzi * @Date: 2024/10/11 14:20 */ public function vga() { // TODO: Implement plug120V() method. $this->chinaPlug->hdmi(); echo '使用介面卡,將HDMI介面轉換為VGA格式' . PHP_EOL; } }
(3)新的資料線類,支援HDMI介面。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/8/1 * Time: 15:50 */ namespace app\admin\service\mode\adapter\other; /** * 新的資料線類,支援HDMI介面 */ class NewDataCable { public function hdmi() { echo "HDMI介面" . PHP_EOL; } }
(4)呼叫方式
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/7/30 * Time: 11:29 */ namespace app\admin\controller\mode\adapter; use app\admin\service\mode\adapter\other\Adapter; use app\admin\service\mode\adapter\other\NewDataCable; class AdapterController { /** * 當你希望使用某個類,但是其介面與其他程式碼不相容時,可以使用介面卡類。 * @return void * @Author: fengzi * @Date: 2024/10/10 15:41 */ public function change() { $adapter = new Adapter(new NewDataCable());
$adapter->vga();
dd('轉換結束,可以使用'); } }
(5)結果展示
2、應用場景2
如果您需要複用一些類,他們處於同一個繼承體系,並且他們又有了額外的一些共同的方法,但是這些共同的方法不是所有都在這一繼承體系中的子類所具有的共性。
例如:有一個相同型別的類檔案,裡面有你要用的方法,但又不全面。這個時候就可以使用介面卡繼承老的介面類,再去實現沒有的方法後去使用。
(1)公共的計算器介面類
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/7/30 * Time: 11:30 */ namespace app\admin\service\mode\adapter; /** * 計算器的介面類 */ interface Calculator { /** * 加法 * @param string $a 加數 * @param string $b 加數 * @param int|null $scale 小數點後保留位數 * @return mixed * @Author: fengzi * @Date: 2024/7/30 11:37 */ public function add(string $a, string $b, ?int $scale=null); /** * 減法 * @param string $minuend 被減數 * @param string $subtrahend 減數 * @param int|null $scale 小數點後保留位數 * @return mixed * @Author: fengzi * @Date: 2024/7/30 11:39 */ public function subtract(string $minuend, string $subtrahend, ?int $scale=null); /** * 乘法 * @param string $a 乘數 * @param string $b 乘數 * @param int|null $scale 小數點後保留位數 * @return mixed * @Author: fengzi * @Date: 2024/7/30 11:41 */ public function multiply(string $a, string $b, ?int $scale=null); /** * 除法 * @param string $dividend 被除數 * @param string $divisor 除數 * @param int|null $scale 小數點後保留位數 * @return mixed * @Author: fengzi * @Date: 2024/7/30 11:44 */ public function divide(string $dividend, string $divisor, int $scale=null); }
(2)公共介面類的具體實現
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/7/30 * Time: 11:31 */ namespace app\admin\service\mode\adapter; /** * 簡單的計算類 */ class SimpleCalculator implements Calculator { /** * 加法 * @param string $a 加數 * @param string $b 加數 * @param int|null $scale 小數點後保留位數 * @return string * @Author: fengzi * @Date: 2024/7/30 11:37 */ public function add(string $a, string $b, int $scale=null): string { // TODO: Implement add() method. return bcadd($a, $b, $scale); } /** * 減法 * @param string $minuend 被減數 * @param string $subtrahend 減數 * @param int|null $scale 小數點後保留位數 * @return string * @Author: fengzi * @Date: 2024/7/30 11:39 */ public function subtract(string $minuend, string $subtrahend, ?int $scale=null): string { // TODO: Implement subtract() method. return bcsub($minuend, $subtrahend, $scale); } /** * 乘法 * @param string $a 乘數 * @param string $b 乘數 * @param int|null $scale 小數點後保留位數 * @return string * @Author: fengzi * @Date: 2024/7/30 11:41 */ public function multiply(string $a, string $b, int $scale=null): string { // TODO: Implement multiply() method. return bcmul($a, $b, $scale); } /** * 除法 * @param string $dividend 被除數 * @param string $divisor 除數 * @param int|null $scale 小數點後保留位數 * @return string * @throws \Exception * @Author: fengzi * @Date: 2024/7/30 11:44 */ public function divide(string $dividend, string $divisor, int $scale=null): string { // TODO: Implement divide() method. if ($divisor == 0) { throw new \Exception("除數不能為零"); } return bcdiv($dividend, $divisor, $scale); } }
(3)繼承公共介面類後擴充套件了其他方法的介面類
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/7/30 * Time: 11:36 */ namespace app\admin\service\mode\adapter; /** * 高階計算類 */ interface AdvancedCalculator extends Calculator { /** * 指數 * @param mixed $base 底數 * @param mixed $exponent 指數 * @return mixed * @Author: fengzi * @Date: 2024/7/30 11:53 */ public function power(mixed $base, mixed $exponent); /** * 平方根 * @param float $number * @return mixed * @Author: fengzi * @Date: 2024/7/30 11:55 */ public function squareRoot(float $number); }
(4)介面卡適配所有方法
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/7/30 * Time: 11:59 */ namespace app\admin\service\mode\adapter; /** * 介面卡 */ class CalculatorAdapter implements AdvancedCalculator { private Calculator $simpleCalculator; public function __construct(SimpleCalculator $simpleCalculator) { $this->simpleCalculator = $simpleCalculator; } /** * 指數運算 * @param mixed $base * @param mixed $exponent * @return float|int|mixed|object * @Author: fengzi * @Date: 2024/10/11 14:51 */ public function power(mixed $base, mixed $exponent) { // TODO: Implement power() method. return pow($base, $exponent); } /** * 平方根 * @param $number * @return float|mixed * @Author: fengzi * @Date: 2024/10/11 14:52 */ public function squareRoot($number) { // TODO: Implement squareRoot() method. return sqrt($number); } /** * 加法 * @param string $a * @param string $b * @param int|null $scale * @return mixed|string * @Author: fengzi * @Date: 2024/10/11 14:52 */ public function add(string $a, string $b, ?int $scale = null) { // TODO: Implement add() method. return $this->simpleCalculator->add($a, $b, $scale); } /** * 減法 * @param string $minuend * @param string $subtrahend * @param int|null $scale * @return mixed|string * @Author: fengzi * @Date: 2024/10/11 14:52 */ public function subtract(string $minuend, string $subtrahend, ?int $scale = null) { // TODO: Implement subtract() method. return $this->simpleCalculator->subtract($minuend, $subtrahend, $scale); } /** * 乘法 * @param string $a * @param string $b * @param int|null $scale * @return mixed|string * @Author: fengzi * @Date: 2024/10/11 14:52 */ public function multiply(string $a, string $b, ?int $scale = null) { // TODO: Implement multiply() method. return $this->simpleCalculator->multiply($a, $b, $scale); } /** * 除法 * @param string $dividend * @param string $divisor * @param int|null $scale * @return mixed|string * @throws \Exception * @Author: fengzi * @Date: 2024/10/11 14:53 */ public function divide(string $dividend, string $divisor, int $scale = null) { // TODO: Implement divide() method. return $this->simpleCalculator->divide($dividend, $divisor, $scale); } }
(5)介面卡呼叫方式
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/7/30 * Time: 11:29 */ namespace app\admin\controller\mode\adapter; use app\admin\service\mode\adapter\CalculatorAdapter; use app\admin\service\mode\adapter\SimpleCalculator; class AdapterController { public function index() { $calculatorAdapter = new CalculatorAdapter(new SimpleCalculator()); $res = $calculatorAdapter->squareRoot(4); dd($res); } }
(6)結果展示