Blogs : Archives
|
|
| < RIFE 1.4 released | Valid use-cases for stateful web components? > |
|
I'm looking into making RIFE easier to setup through annotations. The plan is quite logically to mimic what the current builders (XML, Java, Groovy) do, but then with annotations. I'm a bit stuck though with designing them, and this is mainly due to single element annotations. It feels to me that instead of relying on a fixed Update: this issue is also under discussion at TheServerSide. The problemWhy? Because Consider this annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface Param
{
String value();
}Initially, it might not seem to be a problem, since everybody uses it like this:
@Param("theName")
public class Element1 extends Element
{}However, imagine that several months down the road, you decide that this annotation really should allow people to declare an array of default values. So you change its declaration to:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface Param
{
String value();
String[] defaultValues() default {};
}All of a sudden, none of the existing uses of the annotation are valid anymore, since as soon as there's more than one element present, you need to explicitly name them. All your users now have to shift through all their exisiting code to change the annotations and add an explicit
@Param(value="theName")
public class Element1 extends Element
{}Now this is a big problem, since not only does this impose an unnecessary burden on your users, they also didn't actually declare the value of the parameter but its name instead. The meaning of the explicitly named element is completely wrong. This makes code very difficult to read and just asks for hidden bugs and misinterpretations. The only option that I see at the moment is to never use single element annotations. This sadly makes usability lower when annotations initially only have a single element:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface Param
{
String name();
}
@Param(name="theName")
public class Element1 extends Element
{}The solutionJava should simply detect when an annotation has a single element that has no default value and allow that one to be used without an explicit name. For example:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
public @interface Param
{
String name();
String[] defaultValues() default {};
}This always people to use them in any of the following fashions:
@Param("theName")
public class Element1 extends Element
{}
@Param(name = "theName", defaultValues = {"one", "two"})
public class Element2 extends Element
{}
@Param("theName", defaultValues = {"one", "two"})
public class Element3 extends Element
{}Using this approach, people can easily write semantically correct single element annotations without having to give in on usability and still ensuring that they continue to be semantically correct when their project evolves over time. |
||||||
Comments |
||||||
|
||||||
|
||||||
|
||||||
|
||||||
|
||||||
Add a new comment |
||||||
|
||||||
| < RIFE 1.4 released | Valid use-cases for stateful web components? > |



