您的位置:首页 > 编程语言 > Java开发

JAVA设计模式(三)静态与动态代理模式

2016-12-10 16:07 381 查看
  代理模式:为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。

  通过上面的描述,我们知道在代理模式中存在三个角色。

代理接口:subject。

代理类:ProxySubject。

委托类:RealSubject。

代理类和委托类都实现了代理接口。代理类持有一个委托类的实例。

静态代理

根据上面的描述,可以写出一个简单的代理模式Demo。

代理接口

public interface Subject {
public void doTast();
}


委托类

public class RealSubject implements Subject{

@Override
public void doTast() {
// TODO Auto-generated method stub
System.out.println("RealSubject doTast");
}

}


代理类

public class ProxySubject implements Subject{

private Subject delegate;

public ProxySubject(Subject delegate) {
// TODO Auto-generated constructor stub
this.delegate = delegate;
}
@Override
public void doTast() {
// TODO Auto-generated method stub
System.out.println("ProxySubject doTast");
delegate.doTast();
}

}


客户端调用

RealSubject mRealSubject = new RealSubject();
ProxySubject mProxySubject = new ProxySubject(mRealSubject);//代理类去持有委托类的实例
mProxySubject.doTast();//代理类去执行任务


上面的方式就是静态代理模式了,在代码运行前就已经存在了代理类的class编译文件。

优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。

缺点:

1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。

2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

除了静态代理,JAVA还提供了动态代理。

动态代理

动态代理类是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

JAVA提供了实现动态代理的API。我们先来看看动态代理实现步骤。

1. 实现InvocationHandler接口创建自己的调用处理器

2.创建动态代理。

3.动态创建代理类。

先来看看怎么去创建自己的调用处理器

public class DynamicSubject implements InvocationHandler{

private Object delegate;

public DynamicSubject(Object delegate) {
// TODO Auto-generated constructor stub
this.delegate = delegate;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Object result=method.invoke(delegate, args);
return result;
}

}


接下来对客户端调用中代码做修改。

Subject mRealSubject = new RealSubject();
//创建动态代理
DynamicSubject mDynamicSubject = new DynamicSubject(mRealSubject);

ClassLoader loader=mRealSubject.getClass().getClassLoader();
//动态创建代理类
Subject ProxySubject = (Subject)Proxy.newProxyInstance(loader,new Class[]{Subject.class},mDynamicSubject);
ProxySubject.doTast();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java设计模式