PHP設計模式之代理模式

概念

代理模式(Proxy Pattern) :一種對象結構型模式。給某一個對象提供一個代理,並由代理對象控制對原對象的引用。php

UML

clipboard.png

角色

  1. 抽象主題角色(Subject):定義了RealSubject和Proxy公用接口,這樣就在任何使用RealSubject的地方均可以使用Proxy。html

  2. 真正主題角色(RealSubject):定義了Proxy所表明的真實實體。性能

  3. 代理對象(Proxy):保存一個引用使得代理能夠訪問實體,並提供一個與RealSubject接口相同的接口,這樣代理能夠用來代替實體(RealSubject)。測試

適用場景

根據代理模式的使用目的,常見的代理模式有如下幾種類型:優化

  1. 遠程(Remote)代理:爲一個位於不一樣的地址空間的對象提供一個本地 的代理對象,這個不一樣的地址空間能夠是在同一臺主機中,也但是在 另外一臺主機中,遠程代理又叫作大使(Ambassador)。this

  2. 虛擬(Virtual)代理:若是須要建立一個資源消耗較大的對象,先建立一個消耗相對較小的對象來表示,真實對象只在須要時纔會被真正建立。spa

  3. Copy-on-Write代理:它是虛擬代理的一種,把複製(克隆)操做延遲 到只有在客戶端真正須要時才執行。通常來講,對象的深克隆是一個 開銷較大的操做,Copy-on-Write代理可讓這個操做延遲,只有對象被用到的時候才被克隆。3d

  4. 保護(Protect or Access)代理:控制對一個對象的訪問,能夠給不一樣的用戶提供不一樣級別的使用權限。代理

  5. 緩衝(Cache)代理:爲某一個目標操做的結果提供臨時的存儲空間,以便多個客戶端能夠共享這些結果。code

  6. 防火牆(Firewall)代理:保護目標不讓惡意用戶接近。

  7. 同步化(Synchronization)代理:使幾個用戶可以同時使用一個對象而沒有衝突。

  8. 智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操做,如將此對象被調用的次數記錄下來等。

代碼

代碼以下:

<?php
header("Content-type:text/html;Charset=utf-8");

/**
 * Interface Subject 抽象主題角色
 *
 * 定義RealSubject和Proxy共同具有的東西
 */
interface Subject
{
    public function say();
    public function run();
}

/**
 * Class RealSubject 真正主題角色
 */
class RealSubject implements Subject
{
    // 姓名
    private $_name;

    /**
     * RealSubject constructor. 構造方法
     *
     * @param $name
     */
    public function __construct($name)
    {
        $this->_name = $name;
    }

    /**
     * 說話
     */
    public function say()
    {
        echo $this->_name."在說話<br>";
    }

    /**
     * 在跑步
     */
    public function run(){
        echo $this->_name."在跑步<br>";
    }
}

/**
 * Class Proxy 代理對象
 */
class Proxy implements Subject
{
    // 真實主題對象
    private $_realSubject = null;

    /**
     * Proxy constructor. 構造方法,依賴注入方式儲存真實對象
     *
     * @param RealSubject|null $realSubject
     */
    public function __construct(RealSubject $realSubject = null)
    {
        if (empty($realSubject)) {
            $this->_realSubject = new RealSubject();
        } else {
            $this->_realSubject = $realSubject;
        }
    }

    /**
     * 調用說話方法
     */
    public function say()
    {
        $this->_realSubject->say();
    }

    /**
     * 調用跑步方法
     */
    public function run()
    {
        $this->_realSubject->run();
    }
}

/**
 * Class Client 本地測試
 */
class Client
{
    public static function test()
    {
        // 建立
        $subject = new RealSubject("張三");
        // 代理
        $proxy = new Proxy($subject);
        // 張三在說話
        $proxy->say();
        // 張三在跑步
        $proxy->run();
    }
}

// 測試
Client::test();

運行結果:

張三在說話
張三在跑步

優勢和缺點

優勢:

  1. 代理模式可以協調調用者和被調用者,在必定程度上下降了系統的耦合度。

  2. 遠程代理使得客戶端能夠訪問在遠程機器上的對象,遠程機器 可能具備更好的計算性能與處理速度,能夠快速響應並處理客戶端請求。

  3. 虛擬代理經過使用一個小對象來表明一個大對象,能夠減小系統資源的消耗,對系統進行優化並提升運行速度。

  4. 保護代理能夠控制對真實對象的使用權限。

缺點:

  1. 因爲在客戶端和真實主題之間增長了代理對象,所以 有些類型的代理模式可能會形成請求的處理速度變慢。

  2. 實現代理模式須要額外的工做,有些代理模式的實現很是複雜。

相關文章
相關標籤/搜索