模式简介
代理模式是一种结构型设计模式,它通常用于控制对对象的访问,可以为对象的访问添加一些额外的操作。例如当我们需要测试对象执行某个方法所耗费的时间时,那么就可以通过代理模式在该方法的执行前后记录一次时间并计算时间间隔。通过代理模式可以对原有对象进行访问控制、延迟加载和简化接口。
常见的应用场景:远程代理、虚拟代理、保护代理、缓存代理、日志记录、图片加载优化、数据库连接池、权限管理和动态代理等。
模式结构
-
抽象主题(Subject):
- 定义了真实主题和代理主题的共同接口,客户端通过这个接口访问真实主题或代理主题。
-
真实主题(Real Subject):
- 实现了抽象主题接口,是代理模式中的实际对象,客户端最终要使用的对象。
-
代理主题(Proxy):
- 包含一个引用(指针或引用对象)指向真实主题。
- 实现了抽象主题接口,与真实主题实现相同的接口,使得客户端无需关心真实主题和代理主题的区别。
- 在代理主题中可以控制对真实主题的访问,可以在访问前或访问后执行一些额外的操作,如权限控制、延迟加载、日志记录等。
工作原理
-
客户端通过代理访问真实主题:
- 客户端通常通过抽象主题的接口来访问真实主题,不直接操作真实主题。
-
代理对象控制访问:
- 当客户端通过代理访问真实主题时,代理对象可以在访问前后执行一些操作,例如权限验证、日志记录等。
-
延迟加载(虚拟代理):
- 如果使用了虚拟代理,代理对象在需要时才创建和初始化真实对象,以减少资源消耗。
-
其他附加操作:
- 代理对象还可以实现一些额外的功能,比如缓存、计算结果的缓存、异常处理等。
代码示例(C#)
提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。
调试:Debug.cs
namespace ProxyPattern;
// 调试接口
interface IDebug
{
// 控制台输出
void Log(string content);
}
// 调试
class Debug : IDebug
{
public void Log(string content)
{
Console.WriteLine(content);
}
}
// 调试代理
class DebugProxy : IDebug
{
private Debug debug;
public DebugProxy()
{
debug = new Debug();
}
public void Log(string content)
{
Console.WriteLine("---------------- Begin ----------------");
debug.Log(content);
Console.WriteLine("---------------- End ----------------");
}
}
测试代码:Program.cs
// ************* 13.代理模式测试 **************
using ProxyPattern;
DebugProxy debug = new DebugProxy();
debug.Log("This is a paragraph.");
代码解说
上述代码实现了为每次控制台输出的内容添加前后分隔线的功能。通过代理模式可以避免修改代理对象的源码,从而实现对对象访问的控制。该示例我们完全可以直接在Debug类的Log方法中添加前后分隔线,但是如果现在Debug类的业务逻辑繁多,结构复杂,直接修改源代码会增加风险从而增加维护成本,通过代理模式则可以在不修改源码的基础上来对Log方法进行控制和扩展。
如果这篇文章对你有帮助,请给作者点个赞吧!