php设计模式适配器模式 php设计模式适配器模式

简介

适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起。

其实就是通过一个转换类,这个转换类里面有一个方法,我们用这个转换方法原来的接口转换成需要的接口

UML

角色

  • Target适配目标 : 该角色定义把其他类转换为何种接口,也就是我们的期望接口。

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

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

 php设计模式适配器模式
php设计模式适配器模式

应用场景

如程序数据库有关联mysql、mysqli、pdo、sqlite、postgresql等操作,而你需要根据情况换数据库操作时,可以使用适配器模式统一接口,这样代码中除了数据库配置之外,就不需要做而外的更改。

同理cache(缓存)的场景也是,无论使用memcache还是redis等,在更换的时候都会很方便,节约时间。

:在一些流行框架中都可以看到此模式,详情请自行参阅框架源码。

实现

  1 <?php
  2 header('Content-Type:text/html;charset=utf-8');
  3 /**
  4  * 适配器模式演示代码
  5  * Target适配目标: IDataBase接口
  6  * Adaptee被适配者: mysql和mysql_i、postgresql的数据库操作函数
  7  * Adapter适配器 :mysql类和mysql_i、postgresql类
  8  */
  9 
 10 /**
 11  * Interface IDatabase 适配目标,规定的接口将被适配对象实现
 12  * 约定好统一的api行为
 13  */
 14 interface IDatabase
 15 {
 16     // 定义数据库连接方法
 17     public function connect($host, $username, $password, $database);
 18     // 定义数据库查询方法
 19     public function query($sql);
 20     // 关闭数据库
 21     public function close();
 22 }
 23 
 24 /**
 25  * Class Mysql 适配器
 26  */
 27 class Mysql implements IDatabase
 28 {
 29     protected $connect; // 连接资源
 30 
 31     /**
 32      * 实现连接方法
 33      *
 34      * @param $host host
 35      * @param $username 用户名
 36      * @param $password 密码
 37      * @param $database 数据库名
 38      */
 39     public function connect($host, $username, $password, $database)
 40     {
 41         $connect = mysql_connect($host, $username, $password);
 42         mysql_select_db($database, $connect);
 43         $this->connect = $connect;
 44         //其他操作
 45     }
 46 
 47     /**
 48      * 实现查询方法
 49      *
 50      * @param $sql 需要被查询的sql语句
 51      * @return mi
 52      */
 53     public function query($sql)
 54     {
 55         return mysql_query($sql);
 56     }
 57 
 58     // 实现关闭方法
 59     public function close()
 60     {
 61         mysql_close();
 62     }
 63 }
 64 
 65 /**
 66  * Class Mysql 适配器
 67  */
 68 class Mysql_i implements IDatabase
 69 {
 70     protected $connect; // 连接资源
 71 
 72     /**
 73      * 实现连接方法
 74      *
 75      * @param $host host
 76      * @param $username 用户名
 77      * @param $password 密码
 78      * @param $database 数据库名
 79      */
 80     public function connect($host, $username, $password, $database)
 81     {
 82         $connect = mysqli_connect($host, $username, $password, $database);
 83         $this->connect = $connect;
 84         //其他操作
 85     }
 86 
 87     /**
 88      * 实现查询方法
 89      *
 90      * @param $sql 需要被查询的sql语句
 91      */
 92     public function query($sql)
 93     {
 94         return mysqli_query($this->connect, $sql);
 95     }
 96 
 97     // 实现关闭
 98     public function close()
 99     {
100         mysqli_close($this->connect);
101     }
102 }
103 
104 /**
105  * Class Postgresql 适配器
106  */
107 class Postgresql implements IDatabase
108 {
109     protected $connect; // 连接资源
110 
111     /**
112      * 实现连接方法
113      *
114      * @param $host
115      * @param $username
116      * @param $password
117      * @param $database
118      */
119     public function connect($host, $username, $password, $database)
120     {
121         $this->connect = pg_connect("host=$host dbname=$database user=$username password=$password");
122         //其他操作
123     }
124 
125     /**
126      * 实现查询方法
127      *
128      * @param $sql 需要被查询的sql语句
129      */
130     public function query($sql)
131     {
132         // 其他操作
133     }
134 
135     // 实现关闭方法
136     public function close()
137     {
138 
139     }
140 }
141 
142 
143 /**
144  * 客户端使用演示
145  * 这里以mysql为例
146  * 只要模式设计好,不论有多少种数据库,实现和调用方式都是一样的
147  * 因为都是实现的同一个接口,所以都是可以随意切换的
148  */
149 
150 $host = 'localhost';
151 $username = 'root';
152 $password = 'root';
153 $database = 'mysql';
154 
155 //$client = new Postgresql();
156 //$client = new Mysql();
157 $client = new Mysql_i();
158 $client->connect($host, $username, $password, $database);
159 $result = $client->query("select * from db");
160 while ($rows = mysqli_fetch_array($result)) {
161     var_dump($rows);
162 }
163 $client->close();

运行结果:

 1 array(44) {
 2   [0]=>
 3   string(1) "%"
 4   ["Host"]=>
 5   string(1) "%"
 6   [1]=>
 7   string(4) "test"
 8   ["Db"]=>
 9   string(4) "test"
10   [2]=>
11   string(0) ""
12   ["User"]=>
13   string(0) ""
14   [3]=>
15   string(1) "Y"
16   ["Select_priv"]=>
17   string(1) "Y"
18   [4]=>
19   string(1) "Y"
20   ["Insert_priv"]=>
21   string(1) "Y"
22   [5]=>
23   string(1) "Y"
24   ["Update_priv"]=>
25   string(1) "Y"
26   [6]=>
27   string(1) "Y"
28   ["Delete_priv"]=>
29   string(1) "Y"
30   [7]=>
31   string(1) "Y"
32   ["Create_priv"]=>
33   string(1) "Y"
34   [8]=>
35   string(1) "Y"
36   ["Drop_priv"]=>
37   string(1) "Y"
38   [9]=>
39   string(1) "N"
40   ["Grant_priv"]=>
41   string(1) "N"
42   [10]=>
43   string(1) "Y"
44   ["References_priv"]=>
45   string(1) "Y"
46   [11]=>
47   string(1) "Y"
48   ["Index_priv"]=>
49   string(1) "Y"
50   [12]=>
51   string(1) "Y"
52   ["Alter_priv"]=>
53   string(1) "Y"
54   [13]=>
55   string(1) "Y"
56   ["Create_tmp_table_priv"]=>
57   string(1) "Y"
58   [14]=>
59   string(1) "Y"
60   ["Lock_tables_priv"]=>
61   string(1) "Y"
62   [15]=>
63   string(1) "Y"
64   ["Create_view_priv"]=>
65   string(1) "Y"
66   [16]=>
67   string(1) "Y"
68   ["Show_view_priv"]=>
69   string(1) "Y"
70   [17]=>
71   string(1) "Y"
72   ["Create_routine_priv"]=>
73   string(1) "Y"
74   [18]=>
75   string(1) "N"
76   ["Alter_routine_priv"]=>
77   string(1) "N"
78   [19]=>
79   string(1) "N"
80   ["Execute_priv"]=>
81   string(1) "N"
82   [20]=>
83   string(1) "Y"
84   ["Event_priv"]=>
85   string(1) "Y"
86   [21]=>
87   string(1) "Y"
88   ["Trigger_priv"]=>
89   string(1) "Y"
90 }

从以上结果可看出,数据库连接以及查询语句都已经执行成功。