gpt4 book ai didi

java - 设计代理类的实际目的是什么?

转载 作者:行者123 更新时间:2023-12-01 14:09:10 25 4
gpt4 key购买 nike

我一直在研究代理类,但我不明白设计它的全部想法。

从我目前学到的知识来看,它是一个包装对象,可以控制对原始对象的访问。但是如果我们想控制它,为什么我们不能设计具有这些访问机制的原始类。

我读到这些代理对象对于跟踪方法调用、将方法调用路由到远程服务器很有用。

但是我搜索了一个可以在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);

}

}

有人可以向我指出这个代理设计模式发生了什么,它在这个特定程序中做了什么及其优势?

最佳答案

当您处理来自其他团队或第三方的代码时,代理类非常有用,可用于各种诊断或增强操作。
我已经将它们与数据库供应商 JDBC 连接 jar 和容错远程服务器调用一起使用,其中代理可以处理错误或重新连接的故障转移,以便应用程序逻辑在所有客户端调用代码中更清晰。
通过添加以下方法,您的 TraceHandler 可以是一个自包含的类:

@SuppressWarnings("unchecked")
public static <T> T create(final T impl, final Class<?>... interfaces)
{
final Class<?> cls = impl.getClass();

return (T)Proxy.newProxyInstance(cls.getClassLoader(), interfaces, new TraceHandler(impl));
}
然后您可以使用 TraceHandler 来监视/记录您的应用程序使用的任何接口(interface):
SomeObject x = TraceHandler.create(x, SomeObject.class);
FileVisitor myvisitor = TraceHandler.create(visitor, FileVisitor.class)
希望它会更清楚代理类如何有用,示例如下:
public class ProxyTest
{
public static void main(String[] args) {

var elements = new Integer[1000];

for (int i = 0; i < elements.length; i++) {
elements[i] = Integer.valueOf(i);
}

// construct a random integer
Integer key = new Random().nextInt(elements.length) + 1;

Comparator<Integer> comparator = Integer::compare;
Comparator<Integer> comparator2 = TraceHandler.create(comparator, Comparator.class);

// search for the key without proxy
System.out.println("Search for "+key+" without proxy:");
int result = Arrays.binarySearch(elements, key, comparator);

// print match
System.out.println("Found result="+result);

// search for the key with proxy prints debug info per call
System.out.println("Search "+key+" with proxy:");
int result2 = Arrays.binarySearch(elements, key, comparator2);
System.out.println("Found result2="+result2);
}
}
上述运行的示例输出显示代理类可以打印每个比较调用的详细信息。
Search for 486 without proxy:
Found result at 486
Search 486 with proxy:
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(499, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(249, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(374, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(436, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(467, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(483, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(491, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(487, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(485, 486)
stackoverflow.proxy.ProxyTest$$Lambda$1/0x0000000800c00a00@15aeb7ab.compare(486, 486)
Found result at 486

关于java - 设计代理类的实际目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61615058/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com