The virtual field pattern

Yuval Shavit yshavit at akiban.com
Thu Aug 9 10:41:44 PDT 2012


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