我们有两个现成的第三方平台的登录类 QQ 和 Alipay 和自己的登陆类 MyLogin , 他们各自提供了不同的登录方法,为了在我们的主业务代码中能够调用统一的接口来执行登录,我们设计了一个适配器接口 Adapter
, 在不需要修改原类的情况下,通过新增QQAdapter
、AlipayAdapter、MyLoginAdapter
分别继承原有代码并实现 Adpater
接口来实现,不同平台登录接口的统一。
<?php
/**
* QQ提供的登录类
* Class QQ
*/
class QQ {
public function qqLogin($username,$password){
echo $username.' is logining qq with password '. $password. PHP_EOL;
}
}
/**
* 支付宝提供的登录类
* Class Alipay
*/
class Alipay {
public function alipayLogin($config){
echo $config['username'].' is logining alipay with password '. $config['password']. PHP_EOL;
}
}
/**
* 自己提供的登录类
* Class MyLogin
*/
class MyLogin {
public function myLogin($config){
echo $config['username'].' is logining with password '. $config['password']. PHP_EOL;
}
}
/**
* 我们设计的适配器接口
* Interface Adapter
*/
interface Adapter {
public function login($username, $password);
}
/**
* QQ的适配器类(使用继承的适配器模式)
* Class QQAdapter
*/
class QQAdapter extends QQ implements Adapter {
public function login($username, $password) {
$this->qqLogin($username, $password);
}
}
/* 使用组件的适配器模式
class QQAdapter implements Adapter {
public $qq;
public function __construct() {
$this->qq = new QQ();
}
public function login($username, $password) {
$this->qq->qqLogin($username, $password);
}
}
*/
/**
* 支付宝的适配器类
* Class AlipayAdapter
*/
class AlipayAdapter extends Alipay implements Adapter {
public function login($username, $password) {
$this->alipayLogin(['username'=>$username, 'password'=> $password]);
}
}
/**
* 自己的适配器类
* Class MyLoginAdapter
*/
class MyLoginAdapter extends MyLogin implements Adapter {
public function login($username, $password) {
$this->myLogin(['username'=>$username, 'password'=> $password]);
}
}
/**
* 主业务类
* Class User
*/
class User {
private $adapter;
// 方法一:通过普通函数注入适配器
public function setAdapter(Adapter $adapter) {
$this->adapter = $adapter;
}
// 方法二:通过构造函数注入适配器(两种方法不可共存)
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function login($username, $password){
$this->adapter->login($username, $password);
}
}
// 使用方法一
$user = new User();
$adapter = new QQAdapter(); // 实例化QQ适配器
$user->setAdapter($adapter); // 设置适配器
$user->login('xiaoming', '123123');
// 使用方法二
$adpter = new AlipayAdapter(); // 实例化支付宝适配器
$user = new User($adapter); // 设置适配器
$user->login('xiaoming', '123456');
应用场景:将你现有的实现,和第三方库结合起来,就需要使用适配器模式。例如登录、客户端数据库连接
分类:有通过继承模式的适配器,和通过组件模式的适配器;
目的:将一个类的接口转换成可应用的兼容接口。适配器使原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式被用于桥接两个接口,而装饰模式的目的是在不修改类的情况下给类增加新的功能。
适配器模式属于结构型的设计模式。