The virtual field pattern

Brenden Towey brendentowey at gmail.com
Thu Aug 9 12:06:49 PDT 2012


(Resending, apologies to Yuval for my clicko.)

Yes, more boilerplate to fix things which should not be broken in the 
first place.  Reminds me a bit of generics.  The problem is the 
boilerplate obscures what should be a simple idea: private inheritance, 
private implementation.  It's "the vertical problem" where too much code 
gets in the way of straight-forward ideas.

Anyway, I'm not worried about malicious code so much as I am good 
practice.  Encapsulation is a core principle of object oriented 
programming, and the ability to hide complexity, in the form of internal 
implementation, from users.  If people want to be malicious, they can 
muck with the SercurityManager policy and reflection.  The capability to 
be malicious exists now.  It is simply clearly demarcated as beyond the 
pale by the extreme measure one must take to do it.

Public methods require no such measures, and in fact are they are used 
to indicate methods which the user should feel free to call.  It's a 
totally different mind-set.

I'm don't know what "should" happen with protected methods in 
interfaces, but the usefulness of the virtual field pattern decreases 
markedly if the delegate() method must be public.  I'd hate to see a 
repeat of generics, where it seems "practicality" in the short term won 
out, and is now seen as a defect by some. Especially vis-a-vis other 
implementations available in other languages.



On 8/9/2012 10:41 AM, Yuval Shavit wrote:
> It's not too hard to hide that, though it takes a bit of boilerplate. 
> It would involve not just implementing VirtualList<T>, but doing so in 
> a way that returns, as a List<T>, an inne/list class which is itself a 
> VirtualList<T> but adds the invariants:
>
> public class EchoList<E> implements DelegatingList<E> {
>
>     @Override
>     public List<E> getDelegate() {
>         return delegate;
>     }
>
>     private List<E> delegate = new InnerList<E>();
>     private class InnerList<E> implements DelegatingList<E> {
>
>         @Override
>         public List<E> getDelegate() {
>             return innerDelegate;
>         }
>
>         @Override
>         public boolean add(E e) {
>             System.out.println("invariant says hello to " + e);
>             return super.add(e);
>         }
>         private List<E> innerDelegate = new ArrayList<E>();
>     }
> }
>
> So now, while it's true in some sense that you've exposed your 
> implementation via EchoList.getDelegate, you've exposed it in a way 
> that can only easily be accessed as a List<E> which acts exactly like 
> your EchoList<E>.
>
> Someone could get around this by casting getDelegate()'s result to a 
> DelegatingList<E>, at which point they can access the underlying List 
> without triggering your invariant -- so this is not secure if you're 
> worried about malicious users. The boilerplate is also not pretty.
>
> Once/if interfaces get protected methods, one could just make 
> DelegatingList.getDelegate protected (at the cost of binary 
>  compatibility, right? would that be significant?).
>
> On Thu, Aug 9, 2012 at 1:19 PM, Brenden Towey <brendentowey at gmail.com 
> <mailto:brendentowey at gmail.com>> wrote:
>
>     I was thinking that a practical use for this pattern would be, for
>     example, the Collections API, like java.util.List:
>
>     package java.util;
>
>     public interface VirtualList {
>
>        List getDelegateList();
>
>        boolean add( Object o ) default {
>          return getDelegateList().add( o );
>        }
>        ...etc.
>     }
>
>     (Generics omitted for brevity.)  Definitely not a package-private
>     interface.  Nor would I personally guess that the more interesting
>     uses
>     of the virtual field pattern would be "probably" package-private
>     either.  I'd guess they're all public, myself.
>
>
>
>     On 8/9/2012 10:07 AM, Olexandr Demura wrote:
>     > No, its not, since VirtualSomething extends P.
>     > So, its probably package-private interface - will not leak.
>     >
>
>
>



More information about the lambda-dev mailing list