We can also use this pattern not just to decorate but also enhance with additional functionality (like in java.io.Reader implementations). Continuing our example above, with some changes: In this example we did not want to change the return value of foo(), we wanted to enhance the functionality of A, in this case with the additional method bar(). Now, think about what would happen if A had more than one method. You would have to implement all those methods and delegate to the encapsulated instance of A.
Enhancing Using Dynamic Proxy Class
A way to avoid all this work and verbose code is to use Dynamic Proxy Classes:In this example we define BImpl which is a private implementation of B - an interface with the extended functionality. BImpl takes an instance of A and encapsulates it so it can use it for its implementation. The create method creates a proxy object for interface AB (which is A & B). In the proxy, for each method we delegate to the corresponding object according to the origin class of the method.
Limitations
- This implementation relies on the knowledge that A and B are distinct - there are no shared methods. Otherwise we might delegate to the wrong object.
- Overriding a method from A in the proxy is possible but requires more effort to do it right and robust (mainly to method renaming).
No comments:
Post a Comment