The virtual field pattern

Talden talden at gmail.com
Thu Aug 9 17:17:22 PDT 2012


This solution wouldn't work for us where our APIs are used in
scripting language IDEs that use reflection for completion of the
concrete type (not the declared type).  Currently they see public
members that are implementation detail which we need to document for
(lots of 'internal use only' methods is not a good user experience).

Support for lower access specifiers than public in interfaces has
observable value when reflection is involved - when it's not involved
I most people would just like to minimise the boilerplate.

--
Aaron Scott-Boddendijk

On Fri, Aug 10, 2012 at 5:41 AM, Yuval Shavit <yshavit at akiban.com> 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>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