代理模式(Proxy):
代理模式就是给某一个对象提供一个代理,并由代理对象控制对原有对象的引用。在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。例如windows桌面端的快捷方式就是一个代理。
代理模式按照使用目的可以分为:
1)远程代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是本电脑中,也可以在另一台电脑中。如客户端调用web服务或wcf服务。
2)虚拟代理:根据需要创建一个资源消耗较大的对象,使得对象只在需要时才会被真正创建。
3)Copy-on-Write代理:虚拟代理的一种,把复制(或克隆)拖延到只有在客户端需要时,才真正采取行动。
4)保护(Protected or Access)代理:控制一个对象的访问,可以给不同的用户提供不同级别的使用权限。
5)Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以操作这些结果。
6)防火墙(FireWall)代理:保护目标不让恶意用户接近。
7)同步化(Synchronization)代理
8)智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来。
接下来以一个需求案例来说明下代理模式:
现有收费商务信息查询系统的二次开发,增加需求:
1)添加用户身份验证;2)添加日志记录;3)要求以松耦合的方式进行功能添加
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 /* 6 * <?xml version="1.0" encoding="utf-8" ?> 7 * <configuration> 8 * <appSettings> 9 * <add key="proxy" value="Proxy,Proxy.ProxySearcher" /> 10 * </appSettings> 11 * </configuration> 12 */ 13 var proxy = ConfigurationManager.AppSettings["proxy"].Split(","); 14 var searcher = (Searcher)Assembly.Load(proxy[0]).CreateInstance(proxy[1]); 15 var result = searcher.DoSearch("杨过", "玉女心经"); 16 } 17 } 18 19 /// <summary> 20 /// (1) AccessValidator:身份验证类,业务类,它提供方法Validate()来实现身份验证。 21 /// </summary> 22 internal class AccessValidator 23 { 24 //模拟实现登录验证 25 public bool Validate(string userId) 26 { 27 Console.WriteLine($"在数据库中验证用户{userId}是否是合法用户?"); 28 if (userId.Equals("杨过")) 29 { 30 Console.WriteLine("'{0}'登录成功!", userId); 31 return true; 32 } 33 else 34 { 35 Console.WriteLine("'{0}'登录失败!", userId); 36 return false; 37 } 38 } 39 } 40 41 /// <summary> 42 /// (2) Logger:日志记录类,业务类,它提供方法Log()来保存日志。 43 /// </summary> 44 internal class Logger 45 { 46 //模拟实现日志记录 47 public void Log(string userId) 48 { 49 Console.WriteLine($"更新数据库,用户{userId}查询次数加1!"); 50 } 51 } 52 53 /// <summary> 54 /// (3) Searcher:抽象查询类,充当抽象主题角色,它声明了DoSearch()方法。 55 /// </summary> 56 internal interface Searcher 57 { 58 string DoSearch(string userId, string keyWord); 59 } 60 61 /// <summary> 62 /// (4) RealSearcher:具体查询类,充当真实主题角色,它实现查询功能,提供方法DoSearch()来查询信息。 63 /// </summary> 64 internal class RealSearcher : Searcher 65 { 66 public string DoSearch(string userId, string keyWord) 67 { 68 Console.WriteLine($"用户{userId}使用关键词{keyWord}查询商务信息!"); 69 return "返回具体内容"; 70 } 71 } 72 73 /// <summary> 74 /// (5) ProxySearcher:代理查询类,充当代理主题角色,它是查询代理,维持了对RealSearcher对象、AccessValidator对象和Logger对象的引用。 75 /// </summary> 76 internal class ProxySearcher : Searcher 77 { 78 private Searcher searcher; 79 private AccessValidator validator; 80 private Logger logger; 81 82 public ProxySearcher() 83 { 84 searcher = new RealSearcher(); 85 } 86 87 public string DoSearch(string userId, string keyword) 88 { 89 //如果身份验证成功,则执行查询 90 if (this.Validate(userId)) 91 { 92 string result = searcher.DoSearch(userId, keyword); //调用真实主题对象的查询方法 93 this.Log(userId); //记录查询日志 94 return result; //返回查询结果