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

代理设计模式之(静态代理+Java自身提供的动态代理机制)

2012-11-30 09:38 1021 查看
参考:/article/1697327.html

静态代理和动态代理的概念:

由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。

1.代理模式使用的原因:当类违反单一职责原则时,就要去考虑是否采用代理模式实现。

public class ViewAction {
/*
* 设计缺陷:
* 		一个类中有两个功能1.验证激活 2.执行具体操作
* 违反:单一职责原则
* 因此:引入代理机制
*
*/
public void doAction(User user){
//假如用户被激活,则做view操作
if(user.isActive()){
System.out.println("do the viewAction!");
}
}
}

2.引入代理模式(静态代理):解决类违反单一职责原则,使类专注于自己的核心操作

public class AddAction {
public void doAction(User user) {
//添加操作
System.out.println("add..");
}
}
public class ProxyAddAction extends AddAction {
AddAction action = new AddAction();
@Override
public void doAction(User user) {
if (user.isActive()) {
// 代理执行
action.doAction(user);
}
}
}

3.代理模式的优化(静态代理):虽然每一个动作都不相同,但是我们仍可以抽象出一个动作接口。利于系统的扩展。

public interface IAction {
public void doAction(User user);
}

public class AddAction implements IAction {
@Override
public void doAction(User user) {
//添加操作
System.out.println("add..");
}
}
public class ProxyAction implements IAction {
private IAction action;
public ProxyAction(IAction action) {
this.action = action;
}
@Override
public void doAction(User user) {
if (user.isActive()) {
// 代理执行,本质上还是有实现类进行执行
action.doAction(user);
}
}
}

4.动态代理引入的原因:

不仔细深入会觉得与3区别不大,但是确实代理类的编写上灵活很多,因为很多时候系统并非能抽象出统一的接口类,即使能抽象出来也是不符合面向对象的。这时候就可能需要编写不同的代理类。而使用Java API提供的反射机制:正是这种反射机制的使用使得我们调用核心功能更加灵活,而不用依赖于某一个具体的接口,而是依赖于Object对象。

ps:IAction和AddAction的编写与3种一致,不再重复

public class ProxyAction implements InvocationHandler {
private Object action;
public ProxyAction(Object action) {
this.action = action;
}
/*
* 得到代理类的实例
*/
public static Object getInstance(Object action) {
return Proxy.newProxyInstance(action.getClass().getClassLoader(),
action.getClass().getInterfaces(), new ProxyAction(action));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=null;
try {
// 在委派之前作动作,如权限判断等
System.out.println("before method " + method.getName());
//验证是否被激活
if (((User) args[0]).isActive()) {
// 进行委派
result = method.invoke(action, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: "
+ e.getMessage());
} finally {
// 在委派之后做动作
System.out.println("after method " + method.getName());
}
return result;
}
}

5.动态代理的优化:

模板方法模式来对这个代理类进行优化 :BaseProxy类

ps:IAction和AddAction的编写与3种一致,不再重复
public abstract class BaseProxy implements InvocationHandler {
private Object obj;
protected BaseProxy(Object obj) {
this.obj = obj;
}
public static Object getInstance(Object obj, InvocationHandler instance) {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
.getClass().getInterfaces(), instance);
}
@Override
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Object result=null;
try {
this.doBegin();// 代理执行前操作
System.out.println("before method " + m.getName());
//验证是否被激活
if (((User) args[0]).isActive()) {
// 进行委派
result = m.invoke(obj, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: "
+ e.getMessage());
} finally {
System.out.println("after method " + m.getName());
this.doAfter();// 代理执行后操作
}
return result;
}
public abstract void doBegin();
public abstract void doAfter();
}
public class ProxyImpl extends BaseProxy {
protected ProxyImpl(Object obj) {
super(obj);
}
public static Object getInstance(Object foo) {
return getInstance(foo, new ProxyImpl(foo));
}
@Override
public void doBegin() {
System.out.println("do the job before..");

}
@Override
public void doAfter() {
System.out.println("do the job after..");
}
@Override
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
return super.invoke(proxy, m, args);
}
}
总结:[/code]
1.何时代理?
2.代理本身并没有实际操作

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: