This is a straight-forward (default) implementation of the Adapter Pattern.
=> Used frequently!
=> Should be very easy to add...
=> The expected impact is HUGE.
Proposal:
@Adapter
_Create an internal class of the annotated interface/class, which contains all the abstract methods' implementation, such that, each method returns a default value of its declared return type._
Consider the following setup:
public interface SomeIntegers {
public int do_int();
public Integer do_Integer();
}
public interface SomeLongs {
public long do_long();
public Long do_Long();
}
public interface SomeFloats {
public float do_float();
public Float do_Float();
}
...
...
...
public abstract class SomeNumbers implements SomeIntegers, SomeLongs, SomeFloats, ... {
public abstract void do_nothing();
}
Then...
Vanilla Java:
public abstract class SomeThings extends SomeNumber {
public abstract String do_String();
public static abstract class Adapter {
public abstract int do_int() {
return 0;
}
public abstract Integer do_Integer() {
return null;
}
public abstract long do_long() {
return 0L;
}
public abstract Long do_Long() {
return null;
}
public abstract float do_float() {
return 0f;
}
public abstract Float do_Float() {
return null;
}
...
...
...
public abstract void do_nothing() {
return;
}
public abstract String do_String() {
return null;
}
}
}
With Lombok:
@Adapter
public abstract class SomeThings extends SomeNumber {
public abstract String do_String();
}
A few variations (to control with the attributes of the proposed annotation):
null for primitive-wrapper types (Integer, Long, see the example above)@Adapter(primitiveWrapperReturns=PrimitiveWrapperReturns.NULL) - default@Adapter(primitiveWrapperReturns=PrimitiveWrapperReturns.DEFAULT)UnsupportedOperationException instead of returning default@Adapter(throw=false) - default@Adapter(throw=true)I would rather see it in much simpler form. Consider having following interface:
public interface MyStuff {
public void doSomething();
public int calculateSomething();
public Float calculateSomethingPrecisely();
}
When you just want to implement one method doSomething() with Vanilla Java you will have:
public class MyStuffImpl implements MyStuff {
public void doSomething() {
//my code goes here
}
public int calculateSomething() {return 0;} //ignored
public Float calculateSomethingPrecisely() {return 0f;} //ignored
}
but in simpler form with Lombok it could look like:
@Adapter
public class MyStuffImpl implements MyStuff {
public void doSomething() {
//my code goes here
}
}
Plus all the additional configuration you proposed like default returns.
In my example, I was trying to demonstrate the _huge_ amount of boiler-plate code spared due to the proposed @Adapter annotation. I think it's a good example, as, basically, it says: add as many Interfaces, methods, ... - with @Adapter annotation - you won't have to add a single line of code.
@tomekbielaszewski - I think your example is good and simple. It demonstrate yet another point: if a programmer chooses to implement one of the interface method, than it overrides the proposed @Adapter's functionality, for that particular method. In an elegant and intuitive way.
Any progress?
Most helpful comment
In my example, I was trying to demonstrate the _huge_ amount of boiler-plate code spared due to the proposed
@Adapterannotation. I think it's a good example, as, basically, it says: add as many Interfaces, methods, ... - with@Adapterannotation - you won't have to add a single line of code.@tomekbielaszewski - I think your example is good and simple. It demonstrate yet another point: if a programmer chooses to implement one of the interface method, than it overrides the proposed
@Adapter's functionality, for that particular method. In an elegant and intuitive way.