設計模式-代理模式(Proxy)

應用場景:網絡

領導都有祕書,通常會代理領導的部分職能角色,處理簽字、報銷、開會等任務。不少新人可能都只知道祕書的存在,畢竟天天與其打交道,不知道領導的存在。可是領導的的確確是真實存在的。ide

場景說明:函數

代理模式就是建立一個代理對象(祕書),用這個代理對象去表明真實對象。客戶端獲得這個對象之後,跟獲得真實對象同樣來使用。測試

當客戶端操做代理對象時,實際上功能最終仍是會由真實的對象來完成,只不過經過代理來操做而已。最終表現爲,客戶端操做代理,代理操做真實對象,對應上面的,員工都找祕書辦事,祕書統一貫領導彙報。spa

代理對象加載客戶端和被代理的對象中間,咱們就能夠有一些變通,好比說,祕書會對全部事務篩選下,若是事情比較小,比較說請假簽字,祕書可能直接就處理掉了,若是事情比較大,好比說部門預算,祕書就須要向領導彙報。代理

代理模式:爲其它對象提供一種代理以控制對這個對象的訪問。code

代理模式的組成:對象

Subject:目標接口。定義代理對象和具體目標對象的接口,這樣就能夠在任何使用目標對象的地方使用代理對象。繼承

RealSubject:具體的目標對象。真正實現目標接口要求的功能。接口

Proxy:代理對象。他具備如下特徵:

a.實現目標接口Subject,這樣就可使用代理對象來代替具體的目標對象

b.保存一個具體目標對象實例,這樣能夠在須要的時候調用具體目標對象。

c.能夠控制對具體模板對象的訪問。

代碼以下:

Subject和RealSubject類(即領導)的代碼:

/// <summary>
/// 領導管理接口 -Subject
/// </summary>
public interface ManagerAPI
{
    void Handle(Issue aIssue);
}

/// <summary>
/// 領導-RealSubject
/// </summary>
public class Manager : ManagerAPI
{
    public void Handle(Issue aIssue)
    {
        Console.WriteLine("領導處理:{0}", aIssue.Name);
    }
}

代理者Proxy(即祕書)的代碼以下:

/// <summary>
/// 祕書-Proxy,也繼承ManagerAPI 接口
/// </summary>
public class SecretaryProxy : ManagerAPI
{
    /// <summary>
    /// 代理對象內部保存一個具體模板對象、即被代理者的實例,這樣在須要的時候直接調用被代理者
    /// </summary>
    private Manager _manager;

    /// <summary>
    /// 祕書類構造函數,將被代理的對象(領導)做爲參數傳入進來,也能夠經過屬性傳入
    /// </summary>
    /// <param name="aManager"></param>
    public SecretaryProxy(Manager aManager)
    {
        _manager = aManager;
    }

    public void Handle(Issue aIssue)
    {
        //祕書Handle方法中會對事件做一些過濾,若是重要等級低於2級,直接處理掉,不然向領導彙報,請求領導處理
        if (aIssue.IssueLevel < 2)
            Console.WriteLine("祕書處理:{0}", aIssue.Name);
        else
            _manager.Handle(aIssue);
    }
}

測試類代碼:

/// <summary>
/// 代理模式測試類
/// </summary>
public class ProxyTest
{
    public static void Main()
    {
        //領導
        Manager manager = new Manager();
        //祕書,同時代表祕書是領導的代理
        ManagerAPI secretary = new SecretaryProxy(manager);

        Issue issue1 = new Issue("請假三天", 1);
        secretary.Handle(issue1);

        Issue issue2 = new Issue("報銷三萬", 3);
        secretary.Handle(issue2);

        Console.ReadLine();
    }
}

補充描述:

代理模式的實質爲:控制對象訪問

代理模式的幾種用途:

1.遠程代理:一個對象可能存在於不一樣的地址空間。可是客戶端經過遠程代理去調用時,不須要關心這個對象在哪裏,也不關心如何經過網絡去訪問。僅僅是使用代理對象而已

2.虛代理:根據須要來建立大的對象。只有到必須建立對象時,虛代理纔會建立,至關於延遲加載,以時間換空間。

3.保護代理,即上文的例子中對於事務重要等級低於2級,祕書本身處理。代理類中,能夠執行附件的邏輯,如權限控制、業務邏輯控制,而不須要修改被代理的對象。

經過代理從另一種層面增長目標對象的功能。

代理模式的變通:

上面的例子中,真實目標對象(Manager)和代理對象(SecretaryProxy)都實現了ManagerAPI 接口。

實際上,代理對象直接繼承目標對象便可

變通版本的代理模式組成爲:

RealSubject:具體的目標對象,即上文中的領導。

Proxy:代理對象,即上文中的祕書。

他繼承RealSubject,以便直接調用基類方法。真正實現了在客戶端隱藏具體的目標對象。

代碼實現爲:

/// <summary>
/// 領導-RealSubject
/// </summary>
public class Manager
{
    public virtual void Handle(Issue aIssue)
    {
        Console.WriteLine("領導處理:{0}", aIssue.Name);
    }
}

/// <summary>
/// 祕書-Proxy
/// </summary>
public class SecretaryProxy : Manager
{
    public override void Handle(Issue aIssue)
    {
        //祕書Handle方法中會對事件做一些過濾,若是重要等級低於2級,直接處理掉,不然向領導彙報,請求領導處理
        if (aIssue.IssueLevel < 2)
            Console.WriteLine("祕書處理:{0}", aIssue.Name);
        else
            base.Handle(aIssue);
    }
}

/// <summary>
/// 代理模式測試類
/// </summary>
public class ProxyTest
{
    public static void Main()
    {
        //祕書,同時代表祕書是領導的代理
        SecretaryProxy secretary = new SecretaryProxy();

        Issue issue1 = new Issue("請假三天", 1);
        secretary.Handle(issue1);

        Issue issue2 = new Issue("報銷三萬", 3);
        secretary.Handle(issue2);

        Console.ReadLine();
    }
}

簡化版本的代理模式,其實能夠簡單的理解爲類的繼承和方法的重寫。

相關文章
相關標籤/搜索