代理模式应用实例
下面通过一个应用实例来进一步学习和理解代理模式。
实例说明
某软件公司承接了某信息咨询公司的收费商务信息查询系统的开发任务,该系统的基本需求如下:
(1) 在进行商务信息查询之前用户需要通过身份验证,只有合法用户才能够使用该查询系统;
(2) 在进行商务信息查询时系统需要记录查询日志,以便根据查询次数收取查询费用。
该软件公司开发人员已完成了商务信息查询模块的开发任务,现希望能够以一种松耦合的方式向原有系统增加身份验证和日志记录功能,客户端代码可以无区别地对待原始的商务信息查询模块和增加新功能之后的商务信息查询模块,而且可能在将来还要在该信息查询模块中增加一些新的功能。
试使用代理模式设计并实现该收费商务信息查询系统。
实例分析及类图
通过分析,可以采用一种间接访问的方式来实现该商务信息查询系统的设计,在客户端对象和信息查询对象之间增加一个代理对象,让代理对象来实现身份验证和日志记录等功能,而无须直接对原有的商务信息查询对象进行修改,如图3所示:
- 图3 商务信息查询系统设计方案示意图
在图3中,客户端对象通过代理对象间接访问具有商务信息查询功能的真实对象,在代理对象中除了调用真实对象的商务信息查询功能外,还增加了身份验证和日志记录等功能。使用代理模式设计该商务信息查询系统,结构图如图4所示。
- 图4 商务信息查询系统结构图
在图4中,业务类AccessValidator用于验证用户身份,业务类Logger用于记录用户查询日志,Searcher充当抽象主题角色,RealSearcher充当真实主题角色,ProxySearcher充当代理主题角色。
实例代码
(1) AccessValidator:身份验证类,业务类,它提供方法Validate()来实现身份验证。
1 | //AccessValidator.cs |
(2) Logger:日志记录类,业务类,它提供方法Log()来保存日志。
1 | //Logger.cs |
(3) Searcher:抽象查询类,充当抽象主题角色,它声明了DoSearch()方法。
1 | //Searcher.cs |
(4) RealSearcher:具体查询类,充当真实主题角色,它实现查询功能,提供方法DoSearch()来查询信息。
1 | //RealSearcher.cs |
(5) ProxySearcher:代理查询类,充当代理主题角色,它是查询代理,维持了对RealSearcher对象、AccessValidator对象和Logger对象的引用。
1 | //ProxySearcher.cs |
(6) 配置文件App.config,在配置文件中存储了代理主题类类名。
1 |
|
(7) Program:客户端测试类
1 | //Program.cs |
真实主题类继承了抽象主题类,提供了业务方法的具体实现,其典型代码如下:
结果及分析
编译并运行程序,输出结果如下:
1 | 在数据库中验证用户'杨过'是否是合法用户? |
本实例是保护代理和智能引用代理的应用实例,在代理类ProxySearcher中实现对真实主题类的权限控制和引用计数,如果需要在访问真实主题时增加新的访问控制机制和新功能,只需增加一个新的代理类,再修改配置文件,在客户端代码中使用新增代理类即可,源代码无须修改,符合开闭原则。
参考资料:
LoveLion C#设计模式之代理模式(二)