PHP适配器模式怎么用

wen PHP项目 2

本文目录导读:

PHP适配器模式怎么用

  1. 基础概念
  2. 经典实现方式
  3. 实际应用场景
  4. Laravel中的适配器模式
  5. 最佳实践建议
  6. 性能优化技巧

适配器模式(Adapter Pattern)在PHP中非常实用,主要用于解决接口不兼容的问题,我来通过几个实际场景详细讲解。

基础概念

适配器模式允许不兼容的接口协同工作,就像电源转换插头一样,让不同的接口能够对接。

经典实现方式

类适配器(继承方式)

<?php
// 目标接口(客户端期望的接口)
interface PaymentGateway {
    public function pay($amount);
    public function refund($transactionId);
}
// 第三方支付类(不兼容的类)
class ThirdPartyPay 
{
    public function sendMoney($amount) {
        return "通过第三方支付: {$amount}元";
    }
    public function returnMoney($id) {
        return "退款编号: {$id}";
    }
}
// 适配器类
class PaymentAdapter extends ThirdPartyPay implements PaymentGateway 
{
    public function pay($amount) {
        // 转换接口
        return $this->sendMoney($amount);
    }
    public function refund($transactionId) {
        // 转换接口
        return $this->returnMoney($transactionId);
    }
}
// 客户端使用
class OrderService {
    private $paymentGateway;
    public function __construct(PaymentGateway $gateway) {
        $this->paymentGateway = $gateway;
    }
    public function checkout($amount) {
        return $this->paymentGateway->pay($amount);
    }
}
// 使用示例
$adapter = new PaymentAdapter();
$order = new OrderService($adapter);
echo $order->checkout(100);

对象适配器(组合方式)- 推荐

<?php
// 接口定义
interface Notification {
    public function send($to, $message);
}
// 微信通知(不兼容的接口)
class WeChatNotifier 
{
    public function sendWeChat($openId, $content) {
        return "微信发送给 {$openId}: {$content}";
    }
}
// 邮件通知(不兼容的接口)
class EmailNotifier 
{
    public function sendEmail($address, $subject, $body) {
        return "邮件发送给 {$address}: {$subject} - {$body}";
    }
}
// 统一的适配器
class NotificationAdapter implements Notification {
    private $target;
    public function __construct($target) {
        $this->target = $target;
    }
    public function send($to, $message) {
        if ($this->target instanceof WeChatNotifier) {
            return $this->target->sendWeChat($to, $message);
        }
        if ($this->target instanceof EmailNotifier) {
            return $this->target->sendEmail($to, '系统通知', $message);
        }
        throw new Exception("不支持的适配器类型");
    }
}
// 客户端使用
class UserService {
    private $notifier;
    public function __construct(Notification $notifier) {
        $this->notifier = $notifier;
    }
    public function sendNotification($user) {
        return $this->notifier->send($user->getContact(), "欢迎加入");
    }
}
// 使用示例
$userService = new UserService(
    new NotificationAdapter(new WeChatNotifier())
);

实际应用场景

场景1:数据库操作统一接口

<?php
// 统一的缓存接口
interface CacheInterface {
    public function get($key);
    public function set($key, $value, $expire = 300);
    public function delete($key);
}
// Redis实现
class RedisCache {
    private $redis;
    public function __construct() {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }
    public function getData($key) {
        return $this->redis->get($key);
    }
    public function setData($key, $data, $ttl) {
        return $this->redis->setex($key, $ttl, $data);
    }
    public function remove($key) {
        return $this->redis->del($key);
    }
}
// Memcached实现
class MemcachedCache implements CacheInterface {
    private $memcached;
    public function __construct() {
        $this->memcached = new Memcached();
        $this->memcached->addServer('localhost', 11211);
    }
    public function get($key) {
        return $this->memcached->get($key);
    }
    public function set($key, $value, $expire = 300) {
        return $this->memcached->set($key, $value, $expire);
    }
    public function delete($key) {
        return $this->memcached->delete($key);
    }
}
// Redis适配器
class RedisCacheAdapter implements CacheInterface {
    private $redisCache;
    public function __construct(RedisCache $redisCache) {
        $this->redisCache = $redisCache;
    }
    public function get($key) {
        return $this->redisCache->getData($key);
    }
    public function set($key, $value, $expire = 300) {
        return $this->redisCache->setData($key, $value, $expire);
    }
    public function delete($key) {
        return $this->redisCache->remove($key);
    }
}
// 业务逻辑使用
class ProductService {
    private $cache;
    public function __construct(CacheInterface $cache) {
        $this->cache = $cache;
    }
    public function getProduct($id) {
        // 先查缓存
        $cached = $this->cache->get("product:{$id}");
        if ($cached) {
            return unserialize($cached);
        }
        // 数据库查询逻辑...
        $product = ['id' => $id, 'name' => '商品名称'];
        // 写入缓存
        $this->cache->set("product:{$id}", serialize($product));
        return $product;
    }
}
// 切换缓存系统只需改变适配器
$cache = new RedisCacheAdapter(new RedisCache());
$productService = new ProductService($cache);

场景2:第三方API集成

<?php
// 短信发送接口
interface SmsSender {
    public function send($phone, $message);
}
// 阿里云短信
class AliYunSms {
    public function sendSms($params) {
        // Api具体调用逻辑
        return "阿里云发送: {$params['phone']} - {$params['message']}";
    }
}
// 腾讯云短信
class TencentSms {
    public function sendMessage($mobile, $content, $sign) {
        return "腾讯云发送: {$mobile} - {$content} (签名: {$sign})";
    }
}
// 阿里云适配器
class AliYunAdapter implements SmsSender {
    private $aliYun;
    public function __construct(AliYunSms $aliYun) {
        $this->aliYun = $aliYun;
    }
    public function send($phone, $message) {
        return $this->aliYun->sendSms([
            'phone' => $phone,
            'message' => $message,
        ]);
    }
}
// 腾讯云适配器
class TencentAdapter implements SmsSender {
    private $tencent;
    public function __construct(TencentSms $tencent) {
        $this->tencent = $tencent;
    }
    public function send($phone, $message) {
        return $this->tencent->sendMessage($phone, $message, '【公司名称】');
    }
}
// 配置类
class SmsConfig {
    public static function getSmsSender() {
        $provider = env('SMS_PROVIDER', 'aliyun');
        if ($provider === 'aliyun') {
            return new AliYunAdapter(new AliYunSms());
        }
        if ($provider === 'tencent') {
            return new TencentAdapter(new TencentSms());
        }
        throw new Exception("不支持的短信服务商");
    }
}
// 使用
class UserController {
    public function sendVerifyCode($phone) {
        $sender = SmsConfig::getSmsSender();
        $code = rand(100000, 999999);
        return $sender->send($phone, "验证码: {$code}");
    }
}

Laravel中的适配器模式

<?php
namespace App\Adapters;
// 在Laravel中,适配器常用于Service Provider
use Illuminate\Support\ServiceProvider;
class PaymentServiceProvider extends ServiceProvider 
{
    public function register() 
    {
        $this->app->singleton(PaymentGateway::class, function ($app) {
            $driver = config('payment.driver');
            switch ($driver) {
                case 'stripe':
                    return new StripeAdapter(new StripeClient());
                case 'alipay':
                    return new AlipayAdapter(new AlipayClient());
                default:
                    throw new \Exception("不支持的支付方式");
            }
        });
    }
}

最佳实践建议

适配器结构

<?php
// 定义统一的适配器接口
interface CacheAdapter {
    public function get($key);
    public function set($key, $value, $ttl = null);
    public function delete($key);
    public function clear();
}
// 抽象基础适配器
abstract class BaseCacheAdapter implements CacheAdapter {
    protected $client;
    protected function validateKey($key) {
        if (empty($key)) {
            throw new \InvalidArgumentException("Key cannot be empty");
        }
    }
    protected function serializeData($data) {
        return serialize($data);
    }
    protected function unserializeData($data) {
        return unserialize($data);
    }
}

注意事项

  • 接口隔离:适配不同接口,但保持简单
  • 错误处理:适配器要处理好异常
  • 测试友好:方便Mock和测试
  • 性能考虑:避免过度复杂转换

实战要点

<?php
// 统一异常处理
class AdapterException extends \Exception {}
interface ExportAdapter {
    public function export($data, $type);
}
class JsonAdapter implements ExportAdapter {
    public function export($data, $type) {
        if ($type !== 'json') {
            throw new AdapterException("Format not supported");
        }
        return json_encode($data);
    }
}
class XmlAdapter implements ExportAdapter {
    public function export($data, $type) {
        if ($type !== 'xml') {
            throw new AdapterException("Format not supported");
        }
        // XML转换逻辑
        return $this->arrayToXml($data);
    }
}
// 工厂模式结合适配器
class ExportFactory {
    public static function create($format) {
        $adapters = [
            'json' => new JsonAdapter(),
            'xml' => new XmlAdapter(),
        ];
        if (!isset($adapters[$format])) {
            throw new AdapterException("Unsupported format: {$format}");
        }
        return $adapters[$format];
    }
}

性能优化技巧

<?php
// 适配器缓存
class AdapterCache {
    private static $instances = [];
    public static function get($adapterClass) {
        if (!isset(self::$instances[$adapterClass])) {
            self::$instances[$adapterClass] = new $adapterClass();
        }
        return self::$instances[$adapterClass];
    }
}
// 延迟加载
class LazyLoadAdapter implements Notification {
    private $target;
    private $targetClass;
    public function __construct($targetClass, $options = []) {
        $this->targetClass = $targetClass;
        $this->options = $options;
    }
    private function getTarget() {
        if (!$this->target) {
            $this->target = new $this->targetClass($this->options);
        }
        return $this->target;
    }
    public function send($to, $message) {
        return $this->getTarget()->send($to, $message);
    }
}

适配器模式在PHP中:

  • 核心价值:让不兼容代码协同工作
  • 使用场景:第三方集成、遗留系统整合、统一接口
  • 实现要点:接口清晰、转换简单、错误处理完善
  • 实际应用:支付、短信、缓存、文件存储等系统集成

适配器是为了适配,不是重构,如果两套接口本质相同,只是表达方式不同,才适合用适配器。

抱歉,评论功能暂时关闭!