之前在设计模式这本书里面看到代理模式,当时不是很理解,最近回头再看这些东西,有了很多新的理解,这里我准备用尽量通俗的语言来说一说java代理的静态代理。
代理这个东西,乍一看似乎很不好理解,我之前说了,别把专业名词想的太复杂。举个例子,歌手都有个经纪人,这里的经纪人就是一个代理,歌手接商业演出,都是委托给经纪人去洽谈,经纪人谈好之后,歌手知道,我接了这个商演,而歌手很少去和演出方进行洽谈,经纪人持有了歌手这个对象,可以去完成一些活动。
非要用概念一点的术语描述的话,就是代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。同时代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
下面通过一些代码来实现这样的一个代理过程,这里还是用上面的歌手,经纪人的例子。
首先定义一个接口,这个接口的作用是实现用来接演出。
package com.wst.proxy;
/**
* 这个接口用来实现接受演出的功能
* @author wst
*
*/
public interface AcceptShow {
public void acceptShow();
}
下面是一个歌手实现接演出的类
package com.wst.proxy;
/**
*
* @author wst
*
*/
public class Singer implements AcceptShow{
@Override
public void acceptShow() {
System.out.println("我是亚当莱文,我接受了wst和my的婚礼演唱sugar的邀请");
}
}
下面是经纪人代理类
package com.wst.proxy;
/**
* 经纪人Agent,这是一个代理 实现接受商演的接口
* @author wst
*
*/
public class AgentProxy implements AcceptShow{
private Singer singer;//作为一个经纪人代理,需要在构造方里传入歌手的这个对象
public AgentProxy(Singer singer){
this.singer=singer;
}
@Override
public void acceptShow() {
System.out.println("经纪人洽谈,完成相关工作");
singer.acceptShow();
}
}
最后是客户端测试类
package com.wst.proxy;
/**
* 客户端用来测试经纪人代理
* @author wst
*
*/
public class Client {
public static void main(String[] args) {
Singer singer=new Singer();
AgentProxy agent=new AgentProxy(singer);
agent.acceptShow();
}
}
运行的结果
经纪人洽谈,完成相关工作
我是亚当莱文,我接受了wst和my的婚礼演唱sugar的邀请
上面就是一个静态代理模式的演示过程, 就是这样,真正的业务功能还是由委托类来实现,在委托类调用真正的业务功能之前,我们可以做一些其他的类似于日志,信息过滤的操作。
可能看到这你还是没明白,为什么非要使用一个代理模式呢,这里还是要看大家一个理解程度了,proxy对于真实类起到了很好的一个封装,而且客户端只需知道代理类即可,不需要直接操作我们的实现类,尽管我们的代理也是一个实现类,但是代理类是为了给客户端进行调用。
当然,看到这能够有一点理解的小伙伴就会发现静态代理自身存在着一些不可避免的缺陷,首先我们的代理类和委托类实现了同一个接口,万一这个接口增加了而一个方法,那么所有的实现类也需要同时实现,这样无形中增加了而大量的代码,难以维护,其次,这里的代理类代理的是同一中类型的对象,当我们需要对其他类型进行代理的时候们,需要创建新的代理类,即静态代理类只能为特定的接口(Service)服务。如想要为多个接口服务则需要建立很多个代理类。
时间不怎么够,明天我会说一下java代理的动态代理,看不懂没关系,多看几遍就好了。