设计模式 - 适配器模式 (四)

一、什么是适配器模式(Adapter Pattern)?

      适配器模式,就是将不同的api接口,统一成一致的;实际应用举例,数据库操作有mysql、mysqli、pdo三种,但是它们的连接和操作方法是不一样的,我们可以用适配器将它们的操作接口封装成一致的。

     类似场景还有cache适配器,将memcache、redis、file、apc等不同缓存函数适配一致;

     适配器UML图

二、实现适配器

首先来了解三个类 的角色

1、Target适配目标 : 该角色定义把其他类转换为何种接口,也就是我们的期望接口。(可以是具体或抽象类,也可以是接口)

2、Adaptee被适配者 :就是需要被适配的接口。

3、Adapter适配器:其他的两个角色都是已经存在的角色,而适配器角色是需要新建立的,它用来对Adaptee与Target接口进行适配。

<?php
//用户所期待的接口 目标接口
Interface Target{
    public function connect($host, $user, $passwd, $dbname);
    public function query($sql);
    public function close();
}

// MySQL 被适配的类,此类继承了Target
class MySQLAdaptee implements Target
{
    protected $conn;    //用于存放数据库连接句柄
    //实现连接方法
    public function connect($host, $user, $passwd, $dbname)
    {
       // mysql 连接数据库代码块
    }
    //查询方法
    public function query($sql)
    {
        // mysql 查询代码块
    }
    //关闭方法
    public function close()
    {
        // mysql 关闭代码块
    }
}

// MySQLi 需要被适配的类,未继承Target类 (此类可继承Target,不过继承后,里面的方法需要和Target的方法一致)
class MySQLiAdaptee 
{
    protected $conn;
    public function mysqliConnect($host, $user, $passwd, $dbname)
    {
       // mysqli 连接数据库代码块
    }
    public function mysqliQuery($sql)
    {
       // mysqli查询数据库代码块
    }
    public function mysqliClose()
    {
       // mysqli 关闭数据库代码块
    }
}

// 适配器类Adapter ,此类为mysqli的适配器
class MysqliAdapter implements Target{  
    private $adaptee;  
    function __construct($adaptee) {  
        $this->adaptee = $adaptee;   
    } 
    //这里把异类的方法转换成了 接口标准方法,下同
    public function connect(){
        $this->adaptee->mysqliConnect();
    };
    public function query(){
        $this->adaptee->mysqliQuery();
    };
    public function close(){
        $this->adaptee->mysqliClose();
    };
}



// 用户调用
$db = new MySQLAdaptee();  // 使用mysql方式
$db = new MysqliAdapter(new MySQLiAdaptee());  // 使用mysqli,以下调用方法与mysql是一致的

$db->connect('127.0.0.1','root','123','myDB');
$db->query('select * from test');
$db->close();

三、总结

      这个适配器模式,看了网上很多种资料,有些资料感觉是个误区,比如以下这种

      

interface IDatabase
{   
    public function connect($host, $username, $password, $dbname);   
    public function query($sql);
    public function close();
}


class Mysql implements IDatabase
{
    protected $connect; // 连接资源
  
    public function connect($host, $username, $password, $dbname)
    {
        // 连接
    }

    public function query($sql)
    {
       // 查询
    }
 
    public function close()
    {
       // 关闭
    }
}


class Mysql_i implements IDatabase
{
    protected $connect; // 连接资源

    public function connect($host, $username, $password, $dbname)
    {
        // 连接
    }

    
    public function query($sql)
    {
       // 查询
    }
   
    public function close()
    { 
        // 关闭
    }
}


$client = new Mysql('127.0.0.1','root','123','mydb');    // 不同数据库操作切换
$client = new Mysql_i('127.0.0.1','root','123','mydb');   // 不同数据库操作切换

$client->connect($host, $username, $password, $database);
$client->query("select * from db");
$client->close();

 

咋一看好像没什么问题,实现了不同数据库类型,一致操作的方法,但是没有点到适配器的重点;

这里面的适配器类就是它本身,且两个类里面的方法名都是一致的,感觉并无意义;

个人理解:应该是不同类的不同方法名,通过适配器使方法变成一致;比如mysql类的connect方法,与mysqli类的mysqliconnect方法,通过适配器,使这两个方法在调用上保持一致;

大家有什么想法可在底下留言一起探讨,如果觉得此篇文章对您有用,请帮忙点个赞,谢谢!^_^

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值