【发布时间】:2020-05-05 14:07:20
【问题描述】:
我一直在研究代理类,但我并没有完全理解如何设计它。
从我目前学到的知识来看,它是一个包装对象,可以控制对原始对象的访问。但是如果我们想控制它,为什么我们不能设计具有这些访问机制的原始类。
我读到这些代理对象对于跟踪方法调用、将方法调用路由到远程服务器很有用。
但我搜索了一个可以在 java 中向我解释这个问题的问题,但我没有找到。
我将说明我所指的书中的方法跟踪程序的代码。
public class ProxyTest {
public static void main(String[] args) throws ClassNotFoundException {
var elements = new Object[1000];
// fill elements with proxies for the integers 1 . . . 1000
for (int i = 0; i < elements.length; i++) {
Integer value = i + 1;
var handler = new TraceHandler(value);
Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Comparable.class}, handler);
elements[i] = proxy;
}
// construct a random integer
Integer key = new Random().nextInt(elements.length) + 1;
// search for the key
int result = Arrays.binarySearch(elements, key);
// print match if found
if (result >= 0)
System.out.println(elements[result]);
}
}
/**
* An invocation handler that prints out the method name and parameters, then
* invokes the original method
**/
class TraceHandler implements InvocationHandler{
private Object target;
/**
* Constructs a TraceHandler
* @param t the implicit parameter of the method call
**/
public TraceHandler(Object t){
target = t;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
// print implicit argument
System.out.print(target);
// print method name
System.out.print("." + m.getName() + "(");
// print explicit arguments
if (args != null){
for (int i = 0; i < args.length; i++){
System.out.print(args[i]);
if (i < args.length - 1)
System.out.print(", ");
}
}
System.out.println(")");
// invoke actual method
return m.invoke(target, args);
}
}
谁能告诉我这个代理设计模式是怎么回事,它在这个特定的程序中做了什么以及它的优势?
【问题讨论】:
-
“为什么我们不能用这些访问机制设计原始类”代理可以与任何类一起工作,包括那些不是你写的
-
@Michael 它可以生成一个全新的类,比如自己生成代码吗?
-
它不是代码生成工具。它允许您在单个方法中处理接口上的所有方法调用。如果不编写在每个方法中具有相同代码的这些接口的实现,您自己就无法做到这一点,这可能会非常重复。
-
@Clarke, Cay S. Horstman Core Java 我猜 :)
-
@jwpol 你说得对,我崇拜那本书!