PROPOSAL: Glue classes based on Extension Methods
Marek Kozieł
develop4lasu at gmail.com
Mon Mar 30 23:27:46 PDT 2009
GENESIS
I simplified glue classes and described it basing on Extension
Methods, but it still can be extended to support static / static
methods "ArrayList<String>..create();" and static variables. The main
difference rely on the way glue method is executed (almost no names
conflicts).
I hope that this version will be easier to understood, especially
the way TypeParameters are split.
AUTHOR: Lasu aka Marek Kozieł
OVERVIEW
FEATURE SUMMARY:
Glue classes allow to execute static methods on objects using double
dot notation.
MAJOR ADVANTAGE:
Simplification of localizing additional functionality
MAJOR BENEFIT(s):
+ New functions can be easy localized (critically important during
introduction new people into project).
+ Security: glue class does not see anything protected.
+ Light binding new functionality with existing classes.
+ Reduction of a number of used classes.
+ It allows to assign methods and functions (static methods) to
arrays, classes, interfaces, …
+ It's proof against the situation that the same method occurs in
class and delegator as well as in two delegators.
+ It allows to link gained(.jar) logic with a new one, what is
impossible before final developer implements his classes.
+ It allows to project compact interfaces and does not worry about
additional logic.
MAJOR DISADVANTAGE:
-
ALTERNATIVES:
Utils classes, more work on project, duplicated code...
EXAMPLES
SIMPLE / ADVANCED EXAMPLE:
See below.
DETAILS
SPECIFICATION:
Extension Methods:
public class Extensions{
public static int countWords(this String str){
return str.Split(...)...;
}
public static String[] split(this String str, boolean trim){
return str.Split(...)...;
}
}
To make it Glue class we extract type linked with 'this' to class
header, remove parameter name occurring after 'this', remove static
word, and use 'this' as simple parameter:
public class base glue (String ){
public int countWords(this){
return this.split(...)...;
}
public String[] split(this, boolean trim){
return this.split(...)...;
}
}
How do we execute methods:
Extension Methods:
int count = “Extension Methods”.countWords();
Glue classes:
base is in import and no other glue method exists with same name for
this object:
int count = “Extension Methods”..countWords();
or
base is in import:
int count = “Extension Methods”..base.countWords();
or
int count = “Extension Methods”..com.some.base.countWords();
GENERICS:
Extension Methods:
public class Extensions{
public static <T> T getLast(this ArrayList<T> list){
return list.get(list.size()-1);
}
public static <T> T getFirstValid(this ArrayList<T> list,
Validator<? super T> validator){
for (T t : list){
if (validator.isValid(t)) return t;
}
return null;
}
}
Glue classes:
public class base <T> glue ( ArrayList<T> ){
public T getLast( this ){
return list.get(list.size()-1);
}
public T getFirstValid( this , Validator<? super T> validator){
for (T t : list){
if (validator.isValid(t)) return t;
}
return null;
}
}
How do we execute methods (glue):
void test(ArrayList<String> list){
System.out.print(“Last:” + list..getLast() );
}
Advanced:
public class base <T> glue ( ArrayList<T> ){
public <S> T getFirstValid( this , Validator<? super T,S>
validator, S condition){
for (T t : list){
if (validator.isValid( t, condition )) return t;
}
return null;
}
}
Execution:
void test(ArrayList<String> list, Condition condition){
System.out.print(“First:” +
list..<Condition>getFirstValid(Condition.validator, condition ) );
}
Notice that T cannot be directly specified while it's always
determined by object used as 'this'
COMPILATION
All methods are compiled to simple static form (like this visible in
extension methods:) , so they can be executed in normal way.
The extracted method header (like: <T> glue (ArrayList<T>)) to class
header is used for grouping methods properly.
Method: <T> $glue (ArrayList<T> nothing){}; is created basing on:
“<T> glue (ArrayList<T>)” and used for matching control and
determining which class is glue type.
TESTING:
Like simple static methods.
LIBRARY SUPPORT:
No.
REFLECTIVE APIS:
No.
OTHER CHANGES:
No.
MIGRATION:
None.
COMPATIBILITY
New jars are fully compatible. Code is only backward compatible.
REFERENCES:
http://msdn.microsoft.com/en-us/library/bb383977.aspx
http://bugs.sun.com/view_bug.do?bug_id=4093687
http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000680.html
More information about the coin-dev
mailing list