有时候,我们的执行类不愿意被客户端看到,又或者我们需要对访问执行类的客户端的权限进行验证,如果权限不够的话就不允许访问,这种需求就是明显的要使用代理模式
1.定义
代理模式——就是给某一个对象提供一个代理,并由代理对象控制对原对象的引用。在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
例如电脑桌面的快捷方式就是一个代理对象,快捷方式是它所引用的程序的一个代理。
UML图拷贝自 链接
2.代码实现
public interface ExecSqlInter { void ExecSql(); } public class DbHelper : ExecSqlInter { public void ExecSql() { // 执行sql语句 } } public class AdminProxy : ExecSqlInter { ExecSqlInter dbHelper = new DbHelper(); string user = string.Empty; public AdminProxy(string user) { this.user = user; } public void ExecSql() { if (user == "admin") { dbHelper.ExecSql(); } } }
上面的代码判断用户是不是管理员,只有是管理员的时候才让执行ExecSql的方法。其实这就是,使用代理来限制客户端,使得只有满足一定条件下的用户,才能去访问被代理的对象。
这就是代理模式最大的用处。
3.特点
优点:将客户端和被代理对象解耦,使得可以在代理类中对访问进行限制,如果限制的方式改变,只需要更换代理对象就可以了
缺点:增加了系统的复杂度,因为在客户端和被代理对象之间添加了一个新的中介,因此访问的效率会降低(这也基本是所有的设计模式的缺点,用效率还换取后期的可扩展性)
4.一些其他的讨论
4.1 装饰模式和代理模式
最开始我在学习代理模式和装饰模式的时候,一直觉得这两个模式好像,都是要继承抽象,要持有被装饰(代理)的对象实例;
最后慢慢看的多了之后才发现两者的不同:
1)装饰模式的功能主要是为装饰类提供新的功能,而代理模式主要还是为了显示客户端对被代理类的访问,两者的使用场景是有差异的。
2)其次最重要的一点,
在使用装饰模式的时候,被装饰对象是要在运行的时候才添加到装饰类中,也就是说,运行过程中是可以修改被装饰类的。这也是为什么装饰类的构造方法都要将被装饰对象传递过来;
而代理模式,被代理的对象在运行前已经是确定的了,因此并不需要在构造方法中传递被代理类的实例。
希望各位学习愉快~