代理模式
一、概述
代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做 Proxy 或 Surrogate,它是一种对象结构型模式。
代理可以简单的理解为代为办理/处理某些事情。代理模式可分为三部分,代理者(Proxy)、实际目标(被代理者 Real Subject)和请求者。代理的工作方式等价于请求者使用代理去访问实际目标。
二、分析
代理,在其最基本的形式中,是一个类,作为其他东西的接口。代理可以连接到任何东西:网络连接、内存中的大对象、文件或其他一些昂贵或无法复制的资源。
简而言之,代理是由客户端调用以访问幕后真实服务对象的包装器或代理对象。使用代理可以简单的转发到真实的对象,或者可以提供额外的逻辑。
在代理中,可以提供额外的功能,例如当对真实对象的操作是资源密集型时进行缓存,或者在调用对真实对象的操作之前检查先决条件。
对于客户端,代理对象的使用与使用真实对象类似,因为两者都实现相同的接口。
优点
- 代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
- 职责清晰
- 高扩展性
- 智能化
缺点
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
适用场景
- 远程代理:本地对象代表远程对象(属于不同地址空间的对象)。本地对象是远程对象的代理,对本地对象的方法调用会导致对远程对象的远程方法调用 。例如:FTP。
- 虚拟代理:是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。使用一个小对象来代表一个大对象,这样就可以达到性能的最优化,如:浏览网页中的延迟加载,先显示一个默认图片,再去加载对应的真是图片。
- 保护代理:用来控制真实对象访问时的权限。
- 智能引用:编程中使用的引用计数。
三、代码实现
- Image 接口
抽象化接口,代理对象和真实对象都需要实现
public interface Image
{
void Display();
}
- RealImage 真实访问对象
/// <summary>
/// 真实访问对象
/// </summary>
public class RealImage : Image
{
private string _fileName;
public RealImage(string fileName)
{
_fileName = fileName;
LoadFromDisk(fileName);
}
public void Display()
{
Console.WriteLine("Displaying " + _fileName);
}
private void LoadFromDisk(string fileName)
{
Console.WriteLine("Loading " + fileName);
}
}
- ProxyImage 代理对象
/// <summary>
/// 代理
/// </summary>
public class ProxyImage : Image
{
private RealImage _realImage;
private string _fileName;
public ProxyImage(string fileName)
{
_fileName = fileName;
}
public void Display()
{
if (null == _realImage)
{
_realImage = new RealImage(_fileName);
}
_realImage.Display();
}
}
- Demo
static void Main(string[] args)
{
Image image = new ProxyImage("Test.png");
// 图像将从磁盘加载
image.Display();
Console.WriteLine();
// 图像不需要从磁盘加载
image.Display();
Console.ReadKey();
}
四、UML 图
参考资料
[1] 代理模式:https://en.wikipedia.org/wiki/Proxy_pattern
[2] 代理模式:https://www.runoob.com/design-pattern/proxy-pattern.html
[3] 代理模式:https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/proxy.html
欢迎关注个人公众号,实时推送最新博文!