一、生活了中的代理
我们在生活中买东西大部分都是从代理商那里购买的,很少是从工厂直接购买。工厂生产的商品也很少是直接零售的。大部分都要通过过代理商来完成自己的销售任务。因为这样工厂就可以花更多的心思在产品的设计和生产上了。而对于代理商来说也会把产品进行精心的包装和售后服务。所以说代理商在现实生活中起到了举足轻重的作用。
二、程序中的代理a) 要为已经存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运算时间、事务管理等等。
b) 编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。
c) 如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类,还是代理类,这样以后很容易切换,譬如:想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。
d) 交叉业务的编程问题即为面向方面(AOP:Aspect oriented program)的编程,AOP的目标就是要使交叉业务模块化。可以采用将切面代码移动到原始方法的周围的方式,这样与直接在方法内部编写切面代码的运行效果是一样的,这种模式可以称为代理模式啦。
三、动态代理技术a) 要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!写成千上百个代理类,那是相当的累啊!
b) JVM可以在运行期间动态生成类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
c) JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
d) CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
e) 代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,可以在代理方法中的如下四个位置加上系统功能代码:
i. 在调用目标方法之前
ii. 在调用目标方法之后
iii. 在调用目标方法前后
iv. 在处理目标方法异常的catch块中
四、举例以论坛中已注册用户和游客的权限不同来作为第一个例子:已注册的用户拥有发帖,修改自己的注册信息,修改自己的帖子等功能;而游客只能看到别人发的帖子,没有其他权限。为了简化代码,更好的显示出代理模式的骨架,我们这里只实现发帖权限的控制。 首先我们先实现一个抽象主题角色MyForum,里面定义了真实主题和代理主题的共同接口——发帖功能。
代码如下:
public interface MyForum
{
public void AddFile();
}
这样,真实主题角色和代理主题角色都要实现这个接口。其中真实的主题角色基本就是将这个接口的方法内容填充进来。所以在这里就不再赘述它的实现。我们把主要的精力放到关键的代理主题角色上。代理主题角色代码大体如下:
public class MyForumProxy implements MyForum
{
private RealMyForum forum ;
private int permission ; //权限值
public MyForumProxy(int permission)
{
forum = new RealMyForum()
this.permission = permission ;
}
//实现的接口
public void AddFile()
{
//满足权限设置的时候才能够执行操作
//Constants是一个常量类
if(Constants.ASSOCIATOR == permission)
{
forum.AddFile();
}
else
System.out.println("You are not a associator of MyForum ,please registe!");
}
}
这样就实现了代理模式的功能。
这样代理模式的功能就在上面体现的淋漓尽致——通过代理来将真实图片的加载放到后台来操作,使其不影响前台的浏览。
五、小总结