代理模式(Proxy)為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)莫其。在某些情況下,一個(gè)對(duì)象不適合或者不能直接引用另一個(gè)對(duì)象锣光,而代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介作用踪危。
角色分析:
1蔬浙、抽象主題角色(IGiveGift):定義了Follower和Proxy公用接口,這樣就在任何使用Follower的地方都可以使用Proxy贞远。
2畴博、主題角色(Follower):定義了Proxy所代表的真實(shí)實(shí)體。
3蓝仲、代理對(duì)象(Proxy):保存一個(gè)引用使得代理可以訪問(wèn)實(shí)體俱病,并提供一個(gè)與Follower接口相同的接口,這樣代理可以用來(lái)代替實(shí)體(Follower)袱结。
優(yōu)點(diǎn):
1亮隙、職責(zé)清晰:真實(shí)的角色就是實(shí)現(xiàn)實(shí)際的業(yè)務(wù)邏輯,不用關(guān)心其它非本職責(zé)的事務(wù)垢夹,通過(guò)后期的代理完成一件事務(wù)溢吻,附帶的結(jié)果就是編程簡(jiǎn)潔清晰。
2果元、代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用促王,這樣起到了中介和保護(hù)了目標(biāo)對(duì)象的作用。
3而晒、高擴(kuò)展性蝇狼。
適用場(chǎng)景:
遠(yuǎn)程代理,也就是為了一個(gè)對(duì)象在不同地址空間提供局部代表倡怎。隱藏一個(gè)對(duì)象存在于不同地址空間的事實(shí)迅耘。
虛擬代理,根據(jù)需要來(lái)創(chuàng)建開銷很大的對(duì)象监署,通過(guò)它來(lái)存放實(shí)例化需要很長(zhǎng)時(shí)間的真實(shí)對(duì)象颤专。
安全代理,用來(lái)控制真實(shí)對(duì)象的訪問(wèn)對(duì)象焦匈。
智能指引血公,取代了簡(jiǎn)單的指針,它在訪問(wèn)對(duì)象時(shí)執(zhí)行一些附加操作缓熟。
1累魔、對(duì)指向?qū)嶋H對(duì)象的引用計(jì)數(shù),這樣當(dāng)該對(duì)象沒有引用時(shí)够滑,可以自動(dòng)釋放它垦写。
2、當(dāng)?shù)谝淮我靡粋€(gè)持久對(duì)象時(shí)彰触,將它裝入內(nèi)存梯投。
3、在訪問(wèn)一個(gè)實(shí)際對(duì)象前,檢查是否已經(jīng)鎖定了它分蓖,以確保其他對(duì)象不能改變它尔艇。
Copy-on-Write代理,他是虛擬代理的一種么鹤,把復(fù)制(克隆)操作延遲到只有在客戶端真正需要時(shí)才執(zhí)行终娃。
例:
//通過(guò)代理實(shí)現(xiàn)MySQL的讀寫分離,如果是讀操作蒸甜,就連接127.0.0.1的數(shù)據(jù)庫(kù)棠耕,寫操作就連接127.0.0.2的數(shù)據(jù)庫(kù)
class Proxy{
??? protected $reader;
??? protected $writer;
??? public function __construct(){
??????? $this->reader = new PDO('mysql:host=127.0.0.1;port=3306;dbname=laravel;','root','root');
??????? $this->writere = new PDO('mysql:host=127.0.0.2;port=3306;dbname=laravel;','root','root');
??? }
??? 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);
??????? }
??? }
}
//數(shù)據(jù)庫(kù)代理
$proxy = new Proxy;
//讀操作
$proxy->query("select * from articles");
//寫操作
//$proxy->query("insert into articles set title = 'hello' ");
//var_dump($a);
//對(duì)于數(shù)據(jù)庫(kù)來(lái)說(shuō):這里應(yīng)該使用單例模式的方法來(lái)存放$reader和writer,但我只是舉個(gè)例子柠新,不想把單例加進(jìn)來(lái)把代碼搞復(fù)雜窍荧。
//但是如果要實(shí)現(xiàn)這樣的一個(gè)數(shù)據(jù)庫(kù)代理,還是有必要用上單例模式的知識(shí)恨憎。