I discovered the Proxy Visitor Pattern after having encountered the “proxy problem”.
In short, the “proxy problem” occurs when you want to cast or test the class of an instance coming from a lazy loaded polymorphic collection. By polymorphic collection, I mean a hibernate collection containing instances of polymorphic object.
Because of the lazy loading process, the true instance are replaced by proxies, therefore the instanceof does not work.
Luckily, The Proxy Visitor Pattern proposes a solution to this issue.
However, recently I had to extend this pattern. I needed the reference of the true instance to pass it as a parameter to another method. Because of the proxy, I couldn’t cast the collection instance. I create a Visitor as followed:
public class VisitorImpl implements Visitor { public static final int FORM_FIELD = 1; public static final int FORM_BLOCK = 2; protected FormElement lastChecked; protected boolean lastCheckedTrace = 0; public boolean isFormField() { return (lastCheckedTrace & FORM_FIELD) != 0; } public boolean isFormBlock() { return (lastCheckedTrace & FORM_BLOCK) != 0; } public FormElement getLastChecked() { return lastChecked; } public void visit(FormField field) { lastChecked = field; lastCheckedTrace = FORM_FIELD; } public void visit(FormBlock block) { lastChecked = block; lastCheckedTrace = FORM_BLOCK; } }
I can check the type of the collection instance proceeding as followed:
... Visitor checker = new Visitor(); for (Object tabElObj : tab.getFormElements()) { FormElement element = (FormElement) tabElObj; //Is the element a form field element.accept(visitor); if (visitor.isFormField()) { // do something with (FormField) visitor.getLastChecked() ... } } ...