代理模式(Proxy Pattern):構建了透明置于兩個不同對象之內的一個對象,從而能夠截取或代理這兩個對象間的通信或訪問。
(一)為什么需要代理模式
1,遠程代理
,也就是為了一個對象在不同地址空間提供局部代表。隱藏一個對象存在于不同地址空間的事實。
2,虛擬代理
,根據需要來創建開銷很大的對象,通過它來存放實例化需要很長時間的真實對象。
3,安全代理
,用來控制真實對象的訪問對象。
4,智能指引
,當調用真實對象的時候,代理處理一些事情。
(二)代理模式UML圖
Proxy Pattern
(三)簡單實例
案例一
:你想買一張學友哥的新唱片,以前你都是在縣城CD店里買的。現在CD行業不景氣,沒得賣了。你只能找人去香港幫你代購一張。
<?php
//代理抽象接口
interface shop{
public function buy($title);
}
//原來的CD商店,被代理對象
class CDshop implements shop{
public function buy($title){
echo "購買成功,這是你的《{$title}》唱片".PHP_EOL;
}
}
//CD代理
class Proxy implements shop{
public function buy($title){
$this->go();
$CDshop = new CDshop;
$CDshop->buy($title);
}
public function go(){
echo "跑去香港代購".PHP_EOL;
}
}
//你93年買了張 吻別
$CDshop = new CDshop;
$CDshop->buy("吻別");
//14年你想買張 醒著做夢 找不到CD商店了,和做夢似的,不得不找了個代理去香港幫你代購。
$proxy = new Proxy;
$proxy->buy("醒著做夢");
案例二
:通過代理實現MySQL的讀寫分離,如果是讀操作,就連接127.0.0.1的數據庫,寫操作就讀取127.0.0.2的數據庫
<?php
class Proxy
{
protected $reader;
protected $wirter;
public function __construct(){
$this->reader = new PDO('mysql:host=127.0.0.1;port=3306;dbname=CD;','root','password');
$this->writer = new PDO('mysql:host=127.0.0.2;port=3306;dbname=CD;','root','password');
}
public function query($sql)
{
if (substr($sql, 0, 6) == 'select')
{
echo "讀操作: ".PHP_EOL;
return $this->reader->query($sql);
}
else
{
echo "寫操作:".PHP_EOL;
return $this->writer->query($sql);
}
}
}
//數據庫代理
$proxy = new Proxy;
//讀操作
$proxy->query("select * from table");
//寫操作
$proxy->query("INSERT INTO table SET title = 'hello' where id = 1");
//當然對于數據庫來說,這里應該使用單例模式的方法來存放$reader和$writer,但我只是舉個例子,不想把單例加進來把代碼搞復雜。
//但是如果你要實現這樣的一個數據庫代理,我覺得還是有必要用上單例模式的知識
一句話來說,代理模式,就是在訪問對象時通過一個代理對象去訪問你想訪問的對象。而在代理對象中,我們可以實現對訪問對象的截斷或權限控制等操作。