关于java代理模式的疑问 真实对象什么时候被创建

首先声明一点:尽管原对象和代理对象是"同一个类型",但是被代理的和原对象不是完全一样的对象,就好比说,原来的大厦叫河蟹大厦,现在我给大厦安装了电梯,但是他还叫河蟹大厦,我们代理之后的对象就是安了电梯的河蟹大厦,电梯没有用么?当然有用了,但是我们安装电梯后要不要使用原来河蟹大厦的功能比如,电灯呢?当然也要了!这就是代理之后和被代理之前的关系,代理当然是有用的啦!

当然你可能会说了:为什么不在设计之初就按上电梯呢?这个。。。很多时候我们是故意为之,当太多类似的函数的里面都需要同一条语句,并且位置都大致相似的时候,我们需要在每个函数里面都添加上么?一次两次还好,多次了你可能就会烦了。一句两句好,如果一下都是10几句,每个函数都一样的,就太“八股文”了。

下面是一个例子吧,算伪代码,只是想让你看看怎么用,不一定能直接运行。

proxy.newProxyInstance()生成的代理对象,是在传入InvocationHandler的对象基础之上“织入”的即改进的,所以你传入的这个对象必须new出来,要不然怎么对其进行改进呢?而一般来说,我们使用的是代理之后的类,而非原始类,代理之后的类可以对原始传入类的一些函数进行拓展,这就是动态代理的用途。

再具个例子吧。。。

我们有很多类,它们都执行不同的SQL语句来连接数据库。如果我们在每个类里面都在查询代码之前先连接数据库,之后关闭数据库连接,那会导致很多的代码重复,这时候如果我们利用代理就是这么一个效果。

public class MyHandler implements InvocationHandler

{

......被代理对象target传入,省略

.....

Object invoke(Object proxy,

Method method,

Object[] args)

{

..做链接数据库

Object obj = proxy.invoke(target,args);

..做关闭数据库

return obj;

}

}

然后执行的时候:

Query target = new Query();

Query advanceTarget = Proxy.newProxyInstance(target.getClass().getClassloader(),target.getClass().getInterfaces(),new MyHandler(target)) ;

上面的代码的意思能看懂吧?

Handler相当于一张标准网,他通过传入target,把它增强为能自动连接数据库,查询完毕后能关闭数据库。

Proxy new的时候,使用“这张网”来增强target,并返回增强之后的数据库,我们之后使用advancdTarget就可以无忧无虑的了!因为不用再考虑关闭数据库和打开数据库这些繁琐的细节了。

以上都是AOP的概念,如果有兴趣可以读读Spring框架的书就能更深刻的理解意思了。希望我写的你都能明白,呵呵。

=========================================================

上次的解答:

首先给你一段代码,其他的代码看完了解释。

// 抽象角色:

abstract public class Subject {

abstract public void request();

}

// 真实角色:实现了Subject的request()方法。

public class RealSubject extends Subject {

public RealSubject() {

}

public void request() {

System.out.println( " From real subject. " );

}

}

// 代理角色:

public class ProxySubject extends Subject {

private RealSubject realSubject; // 以真实角色作为代理角色的属性

public ProxySubject() {

}

public void request() { // 该方法封装了真实对象的request方法

preRequest();

if ( realSubject == null ) {

realSubject = new RealSubject();

}

realSubject.request(); // 此处执行真实对象的request方法

postRequest();

}

private void preRequest() {

// something you want to do before requesting

}

private void postRequest() {

// something you want to do after requesting

}

}

// 客户端调用:

Subject sub = new ProxySubject();

Sub.request();

开始解释,上面看到了,其实正如你说的,如果只是简单的为了Client调用原对象,大可不必这么费尽周折啊!

使用代理的意义是:

1、当某些对象不方便直接调用某对象的时候,多数情况是团队开发中,抽象出接口了,但是实现类还没有出来。所以就使用代理了

2、这种情况更有用:为了让被代理类加强功能,不知道你有没有使用过Spring、Struts等框架,这些框架中经常有“代理”、“织入”等AOP的概念,简单的说就是:你原来有一个人的类,只能吃饭,我现在通过代理,给这个人的类加上了喝水、说话的功能,代理的设计模式就实现了这种静态代理。

注意,这和包装等是不一样的。因为代理类和被代理类有相同的父接口。

以上都是我自己写的解释,水平有限,希望和你继续探讨~