目录
代理模式
引言
定义
模式类图
代理模式类型
远程代理
虚拟代理
图片代理
Copy-on-Write代理
保护代理
缓冲代理
防火墙代理
同步化代理
智能引用代理
动态代理
总结
模式优点
模式缺点
在某些情况下,一个客户不能或者不想直接引用一个对象,此时可以通过一个称之为“代理”的第三方来间接引用。代理可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容或者添加额外的内容。
英文定义:"Provide a surrogate or placeholder for anthor object to control access to it."。
中文定义:给某一给对象提供一个代理,并由代理对象控制对原对象的引用。
代理模式重要等级★★★★☆ 代理模式难度等级★★★☆☆
代理模式包含以下角色:
1.Subject 抽象主题角色
抽象主题角色声明了真实主题和代理主题的公共接口,这样一来任何使用真实主题的地方都可以使用代理主题。
2.Proxy 代理主题角色
代理主题中维护一个真实主题的引用
3. RealSubject 真实主题角色
根据代理模式的使用目的,代理模式有以下几种类型。这些代理模式的实例我有空就不断补充~
远程代理为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)。
如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只有在需要时才真正创建。
图片代理属于虚拟代理的一种实际运用场景,在网页中,图片一般提供一个小图片,当用户需要查看大图时再通过点击图片来激活另一个连接,这样可以提高浏览器速度,不需要一开始就加载那么多大图片。
它是虚拟代理的一种,将复制克隆操作延迟到只有客户端真正需要时才执行。一般来说,一个对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被调用到的时候才克隆。
控制对一个对象的访问,可以给不同用户提供不同级别的使用权限。
保护代理实例-论坛权限控制代理
实例说明
在一个论坛中已注册用户和游客权限不同,已注册的用户拥有发帖、修改自己的注册信息、修改自己的贴子等功能;而游客只能看别人发的帖子,没有其他权限。使用代理模式来设计改权限管理模块。
实例类图
代码实现
抽象权限类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
interface AbstractPermission
{
void ModifyUserInfo();
void ModifyNote();
void ViewNote();
void PublishNote();
void SetLevel(int level);
}
真实主题类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class RealPermission : AbstractPermission
{
public void ModifyNote()
{
Console.WriteLine("修改帖子。");
}
public void ModifyUserInfo()
{
Console.WriteLine("修改用户信息。");
}
public void PublishNote()
{
Console.WriteLine("发帖。");
}
public void SetLevel(int level)
{
throw new NotImplementedException();
}
public void ViewNote()
{
Console.WriteLine("浏览帖子。");
}
}
代理主题类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class PermissionProxy : AbstractPermission
{
private RealPermission permission = new RealPermission();
private int level = 0;
public void ModifyNote()
{
if (0 == level)
Console.WriteLine("权限不足");
else
permission.ModifyNote();
}
public void ModifyUserInfo()
{
if (0 == level)
Console.WriteLine("权限不足");
else
permission.ModifyUserInfo();
}
public void PublishNote()
{
if (0 == level)
Console.WriteLine("权限不足");
else
permission.PublishNote();
}
public void SetLevel(int level)
{
this.level = level;
}
public void ViewNote()
{
permission.ViewNote();
}
}
测试代码
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
class Program
{
static void Main(string[] args)
{
AbstractPermission permission;
permission = new PermissionProxy(); //这一行可配置化
for(int i = 0; i < 2; i++)
{
permission.SetLevel(i);
permission.ViewNote();
permission.PublishNote();
permission.ModifyNote();
permission.ModifyUserInfo();
Console.WriteLine("----------------------");
}
}
}
运行结果
为某一个目标操作提供临时的存储空间,以便多个客户端可以共享这些结果。
保护目标不让恶意用户接近
使几个用户能够同时使用一个对象而没有冲突。
当一个对象被引用时,提供一些额外的操作,如记录该对象被调用的次数。
在代理模式的类图中,代理类维护了一个真实主题角色作为内部成员属性,每个真实主题角色都对应着一个代理主题角色,这意味着系统中的类的个数将会急剧增加。动态代理就是为了解决这个问题,它提供一个动态代理类,用户可以通过配置的方式设置具体真实主题的类名,代理类和真实主题类解耦。
1.代理模式作为一个中介对象,降低了系统的耦合度。
2.远程代理模式突破了计算机性能和处理速度的瓶颈。
3.虚拟代理用小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
4.保护代理可以控制对真实对象的使用权限。
1.有些代理模式的实现非常复杂,编程难度大。
2.客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。