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