I need some advice to which scenarios a dynamic proxy would prove more useful than a regular proxy.
I've put alot of effort into learning how to use dynamic proxies effectively. In this question, set aside that frameworks like AspectJ can perform basically everything we try to achieve with dynamic proxies, or that e.g., CGLIB can be used to address some of the shortcomings of dynamic proxies.
Use cases
- Decorators - e.g., perform logging on method invocation, or cache return values of complex operations
- Uphold contract - That is, making sure parameters are within accepted range and return types conform to accepted values.
- Adapter - Saw some clever article somewhere describing how this is useful. I rarely come across this design pattern though.
Are the others?
Dynamic proxy advantages
- Decorator: Log all method invocations, e.g.,
public Object invoke(Object target, Method method, Object[] arguments) {
System.out.println("before method " + method.getName());
return method.invoke(obj, args);
}
}
The decorator pattern is definately useful as it allows side effects to all proxies methods (although this behaviour is a book-example of using aspects ..).
- Contract: In contrast to a regular proxy, we need not implement the full interface. E.g.,
public Object invoke(Object target, Method method, Object[] arguments) {
if ("getValues".equals(method.getName()) {
// check or transform parameters and/or return types, e.g.,
return RangeUtils.validateResponse( method.invoke(obj, args) );
}
if ("getVersion".equals(method.getName()) {
// another example with no delegation
return 3;
}
}
The contract on the other hand only gives the benefit of avoiding the need to implement a complete interface. Then again, refactoring proxied methods would silently invalidate the dynamic proxy.
Conclusion
So what I see here is one real use case, and one questionable use case. What's your opinion?