The virtual field pattern

Yuval Shavit yshavit at akiban.com
Thu Aug 9 14:26:38 PDT 2012


I don't disagree, and I think you're right that a protected interface
method would be the best solution. But assuming that's not possible, one
way that avoids my boilerplate would be to mark the getDelegate method as
@Deprecated -- and then, when protected interface methods come around, to
bump getDelegate down to protected from public.

On Thu, Aug 9, 2012 at 3:06 PM, Brenden Towey <brendentowey at gmail.com>wrote:

> (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