本文目录导读:

适配器模式(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中:
- 核心价值:让不兼容代码协同工作
- 使用场景:第三方集成、遗留系统整合、统一接口
- 实现要点:接口清晰、转换简单、错误处理完善
- 实际应用:支付、短信、缓存、文件存储等系统集成
适配器是为了适配,不是重构,如果两套接口本质相同,只是表达方式不同,才适合用适配器。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播