The virtual field pattern
Brenden Towey
brendentowey at gmail.com
Thu Aug 9 09:35:42 PDT 2012
It's true that you save some typing, especially for classes with many
methods, but one thing I don't like about this pattern is it forces your
implementation to be public. Other classes can call your "delegate()"
method, and then muck about with your internal implementation.
This is a good reason to allow the protected keyword for interface
methods, in my opinion.
public interface VirtualSomething {
protected P delegate();
T1 m1(...) default {
return delegate().m1(...);
}
T2 m2(...) default {
return delegate().m2(...);
}
.......
}
On 8/9/2012 3:35 AM, Jose wrote:
> Hi all
>
> This post is an elaboration of a comment by Yuval Shavit
>
> http://mail.openjdk.java.net/pipermail/lambda-dev/2012-July/005170.html
>
> After that Brian called this pattern the "virtual field pattern"
>
> http://mail.openjdk.java.net/pipermail/lambda-dev/2012-July/005171.html
>
> I didn't find any refereces to this name, but neither has nothing better to
> offer.
>
> I suppose that programers used to work with Traits would find this post
> trivial, but the pattern was a good surprisse to me because I immedially
> could locate a bunch of places where my code would benefit form it.
>
> I think this pattern shows a simple case where extension methods plays and
> important role in the design of the type hierarchy, independently of API
> evolution.
>
> Lets go:
>
> Let P be an interface
>
> interface P{
> T1 m1(...);
> T1 m2(...);
> .........
> }
>
> and CP a class implementing P:
>
> CP implements P{
> T1 m1(...){...};
> T1 m2(...){...};
> .........
> }
>
> The VirtualField pattern allows you to replace the task of implementing P by
> the task of implementing a Trait
>
> VirtualP
>
> which extends P.
>
> The advantage is that VirtualP has a only a single abstract method to
> implement, one that returns an instance of P.
> Furthermore VirtualP must implement all methods of P by delegation:
>
> interface VirtualP extends P{
> P delegate();
> T1 m1(...) default {
> return delegate().m1(...);
> }
> T2 m2(...) default{
> return delegate().m2(...);
> }
> .......
> }
>
> Let D be a class we want to implement P, but it can't extend CP because it
> already extends another class.
> To have D implementing P we only need to provide these lines of code:
>
> Class D implements VirtualP{
> P delegate=new CP();
> P delegate(){
> return delegate;
> }
> ....
> }
>
> If P has many methods and you have many candidates to implement P, like in
> my case, this pattern saves code and makes these classes more readable.
More information about the lambda-dev
mailing list