1、官方描述:
为其他对象提供一种代理以控制对这个对象的访问。
2、实例讨论:
在进行应用系统开发的时候,往往会有一些信息在部署时才能够确定,并且可能会根据情况进行调整,如数据库配置信息等等,如果把这些信息直接硬编码到程序中,在需要调整时就不得不对系统进行重新编译和发布,这样不仅很麻烦,而且如果系统已经交付给用户使用,那么更是极其的不方便。
怎样解决这些配置信息问题呢,使其既便于修改,而又不对系统产生影响?一个可行的方案是把这些信息写到配置文件中,如Java项目可以写到XML文件或properties文件中,系统在需要这些信息时可以读取配置文件进行获取,这样当需要对配置信息进行调整时可以直接修改这些文件内容,而系统无需再进行编译和发布,这对于已经交付给用户的系统来说无疑也非常的方便。
那么这些信息如何获取呢?每次需要时都直接读取配置文件吗?因为这些配置信息可能会频繁的使用,如果每次都要读取配置文件,那么性能开销将是很大的。这是我们就可以采用Proxy模式,在数据访问对象上进行代理访问,每次需要这些配置信息时,都通过访问代理进行获取,访问代理判断是否已经访问过配置文件并缓存了配置信息,如果已经缓存了,就直接返回缓存的信息,否则在通过真正的DAO进行读取,这个配置文件数据访问模块类结构图如下:

3、代理类型:
Proxy模式在访问对象时提供了一定程度的间接性,这种间接性可以帮助解决某些问题,不同的Proxy解决不同类型的问题,在GOF设计模式中列举了四种代理类型,分别如下:
1)远程代理(Remote Proxy),为一个对象在不同的地址空间提供本地代表;
2)虚代理(Virtual Proxy),根据需要创建开销很大的对象;
3)保护代理(Protection Proxy),控制对原始对象的访问,用于不同的客户端有不同的访问权限;
4)智能指针(Smart Reference),取代了简单指针,在访问对象时执行一些附加操作;
在上面讨论的系统配置信息代理访问ConfigDAOProxy,属于4)智能指针的类型,在这里进行数据缓存以提高数据访问性能的附加能力。
4、实现特征:
1)Proxy和被代理的实体具有相同的接口Subject,这样在被代理实体可以使用的地方就可以用Proxy进行代替;
2)Proxy具有被代理实体的一个引用,以便在需要时把客户端的请求转发给真正的实体;
5、Java代码演示:
下面代码演示了在上面“实例讨论”部分中配置文件读取模块的Java代码结构:
类DataBaseConfig,数据库配置信息值对象:






















接口ConfigDAO,获取配置信息的数据访问接口:







类ConfigDAOImp,实现ConfigDAO,进行实际的从配置文件中读取配置信息操作:
















类ConfigDAOProxy,数据访问代理,实现ConfigDAO,通过ConfigDAOImp进行首次配置信息读入,并加以缓存,以后访问直接从缓存返回,提高系统性能:





























类Client,客户端代码,这里对上面的类进行使用演示:















