设计模式之代理模式
1、类图
代理模式结构:
实例类图:
2、创建项目
…………………………
3、 AccessValidator:身份验证类,业务类,它提供方法Validate()来实现身份验证。
using System;
namespace ProxySample
{
/// <summary>
/// 访问验证类,为业务类
/// </summary>
class AccessValidator
{
//模拟实现登录验证
public bool Validate(string userId)
{
Console.WriteLine("在数据库中验证用户'" + userId + "'是否是合法用户?");
if (userId.Equals("杨过")) {
Console.WriteLine("'{0}'登录成功!",userId);
return true;
}
else {
Console.WriteLine("'{0}'登录失败!", userId);
return false;
}
}
}
}
4、 Logger:日志记录类,业务类,它提供方法Log来保存日志
using System;
namespace ProxySample
{
class Logger
{
//模拟实现日志记录
public void Log(string userId) {
Console.WriteLine("更新数据库,用户'{0}'查询次数加1!",userId);
}
}
}
5、 Searcher:抽象查询类,充当抽象主题角色,它声明了DoSearch()方法。
namespace ProxySample
{
/// <summary>
/// 查询,抽象主题接口
/// </summary>
interface Searcher
{
/// <summary>
/// 执行查询
/// </summary>
/// <param name="userId"></param>
/// <param name="keyword"></param>
/// <returns></returns>
string DoSearch(string userId, string keyword);
}
}
6、 RealSearcher:具体查询类,充当真实主题角色,它实现查询功能,提供方法DoSearch()来查询信息。
using System;
namespace ProxySample
{
/// <summary>
/// 真实主题
/// </summary>
class RealSearcher : Searcher
{
/// <summary>
/// 实现接口方法,模拟查询商务信息
/// </summary>
/// <param name="userId"></param>
/// <param name="keyword"></param>
/// <returns></returns>
public string DoSearch(string userId, string keyword) {
Console.WriteLine("用户'{0}'使用关键词'{1}'查询商务信息!",userId,keyword);
return "返回查询后的具体内容";
}
}
}
7、 ProxySearcher:代理查询类,充当代理主题角色
namespace ProxySample
{
/// <summary>
/// 查询代理
/// </summary>
class ProxySearcher : Searcher
{
/// <summary>
/// 维持一个对真实主题的引用
/// </summary>
private RealSearcher searcher = new RealSearcher();
/// <summary>
/// 用户验证类
/// </summary>
private AccessValidator validator;
/// <summary>
/// 日志记录类
/// </summary>
private Logger logger;
/// <summary>
/// 实现接口,执行查询操作:即通过调用真实对象的方法实现中转
/// </summary>
/// <param name="userId"></param>
/// <param name="keyword"></param>
/// <returns></returns>
public string DoSearch(string userId, string keyword)
{
//如果身份验证成功,则执行查询
if (this.Validate(userId))
{
string result = searcher.DoSearch(userId, keyword); //调用真实主题对象的查询方法
this.Log(userId); //记录查询日志
return result; //返回查询结果
}
else
{
return null;
}
}
/// <summary>
/// 创建访问验证对象并调用其Validate()方法实现身份验证
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public bool Validate(string userId)
{
validator = new AccessValidator();
return validator.Validate(userId);
}
/// <summary>
/// 创建日志记录对象并调用其Log()方法实现日志记录
/// </summary>
/// <param name="userId"></param>
public void Log(string userId)
{
logger = new Logger();
logger.Log(userId);
}
}
}
8、 配置文件App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="proxy" value="ProxySample.ProxySearcher"/>
</appSettings>
</configuration>
9、 Program:客户端测试类
using System;
using System.Configuration;
using System.Reflection;
namespace ProxySample
{
class Program
{
static void Main(string[] args)
{
//读取配置文件
string proxy = ConfigurationManager.AppSettings["proxy"];
//反射生成对象,针对抽象编程,客户端无须分辨真实主题类和代理类
Searcher searcher;
searcher = (Searcher)Assembly.Load("ProxySample").CreateInstance(proxy);
//得到查询结果
String result = searcher.DoSearch("杨过", "玉女心经");
Console.Read();
}
}
}
10、 结果及分析,编译并运行程序,输出结果如下: