代理模式 (Proxy Pattern)【使用频率:★★★★☆】

1. 概述:

  给某一个对象提供一个代理,并由代理对象来控制对原对象的访问。

2. 模式中的角色

    2.1 Subject(抽象对象):它声明了真实对象和代理对象的共同接口,这样一来在任何使用真实对象的地方都可以使用代理对象,客户端通常需要针对抽象对象角色进行编程。

       2.2 Proxy(代理对象):代理对象与真实对象实现相同的接口,所以它能够在任何时刻都能够代理真实对象。代理对象内部包含有对真实对象的引用,所以她可以操作真实对象,同时也可以附加其他的操作,相当于对真实对象进行封装。

       2.3 RealSubject(真实对象):它定义了所代表的真实对象,在真实对象角色中实现了真实的业务操作,客户端可以通过代理对象间接调用真实对象中定义的操作。

3. 模式解读

  3.1 模式的类图

C#设计模式读书笔记之代理模式 (Proxy Pattern)_代理模式

       3.2 代码实现

       读大学的时候都追过女生吧!某天你看到一位美女,一见钟情,心里发誓要她做你女朋友。但是你想这样直接上去可能会唐突了。于是你采用迂回政策,先和她室友搞好关系,然后通过她室友给她礼物。

using System;

namespace ConsoleApp2
{
class Class26
{
static void Main(string[] args)
{
BeautifulGirl mm = new BeautifulGirl("沈佳宜");

Roommate roommate = new Roommate(mm);

roommate.GiveBook();
roommate.GiveChocolate();
roommate.GiveFlowers();

Console.ReadLine();
}
}

public class BeautifulGirl
{
string name;

public BeautifulGirl(string name)
{
this.name = name;
}

public string getName()
{
return name;
}

public void setName(string name)
{
this.name = name;
}
}

// Subject(抽象对象)声明了真实对象和代理对象的共同接口
public interface IGiveGift
{
// 送花
void GiveFlowers();

// 送巧克力
void GiveChocolate();

// 送书
void GiveBook();
}

// RealSubject(真实对象)实现真正的业务逻辑
public class Boy : IGiveGift
{
BeautifulGirl mm; //美女
public Boy(BeautifulGirl mm)
{
this.mm = mm;
}

public void GiveBook()
{
Console.WriteLine(mm.getName() + ",送你一本书....");
}

public void GiveChocolate()
{
Console.WriteLine(mm.getName() + ",送你一盒巧克力....");
}

public void GiveFlowers()
{
Console.WriteLine(mm.getName() + ",送你一束花....");
}
}

// Proxy(代理对象)通过代理对象间接调用真实对象中定义的操作
public class Roommate : IGiveGift
{
Boy boy;
public Roommate(BeautifulGirl mm)
{
boy = new Boy(mm);
}

public void GiveBook()
{
boy.GiveBook();
}

public void GiveChocolate()
{
boy.GiveChocolate();
}

public void GiveFlowers()
{
boy.GiveFlowers();
}
}
}

  输出结果:

C#设计模式读书笔记之代理模式 (Proxy Pattern)_Proxy Pattern_02

好了礼物已经送出去了,能不能搞定就看你的魅力了!!!!

4. 模式优缺点

  4.1 优点:

       (1) 能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。

       (2) 客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵活性和可扩展性。

  4.2 缺点:

       (1) 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。

       (2) 实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂,例如远程代理。

 

5. 使用场景:

       (1) 当客户端对象需要访问远程主机中的对象时可以使用远程代理。

       (2) 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。

       (3) 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。

       (4) 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。

       (5) 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

 

附录:

       (1) 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。

       (2) 虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。

       (3) 保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。

       (4) 缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

       (5) 智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。