-
Notifications
You must be signed in to change notification settings - Fork 0
Good practices
As CodeAPI structures are composed by a lot of instructions and parts, it is easy to write an unreadable code, then I will recommend you to follow these rules:
A simple example is that:
TypeDeclaration declaration = ClassDeclaration.Builder.builder()
.qualifiedName("my.cl")
.modifiers(CodeModifier.PUBLIC)
.fields(FieldDeclaration.Builder.builder()
.modifiers(CodeModifier.PRIVATE, CodeModifier.FINAL)
.type(String.class)
.name("a")
.build()
)
.constructors(ConstructorDeclaration.Builder.builder()
.modifiers(CodeModifier.PUBLIC)
.parameters(Factories.parameter(String.class, "a"))
.body(CodeSource.fromPart(
Factories.setThisFieldValue(String.class, "a", Factories.accessVariable(String.class, "a"))
))
.build())
.build();
If you want to change the name of variable, there is 4 locations where you need to change, and if you want to change modifiers of all fields (when you have more than one) you need to change in all locations where field declaration occurs, a better (and recommended) way to write that is:
private static final VariableRef aField = new VariableRef(String.class, "a");
public static TypeDeclaration create(String className) {
return ClassDeclaration.Builder.builder()
.qualifiedName(className)
.modifiers(CodeModifier.PUBLIC)
.fields(Example.declarePrivateField(aField))
.constructors(Example.createDefinitionConstructor(new VariableRef[]{aField}))
.build();
}
public static FieldDeclaration declarePrivateField(VariableRef ref) {
return FieldDeclaration.Builder.builder()
.modifiers(CodeModifier.PRIVATE, CodeModifier.FINAL)
.type(ref.getType())
.name(ref.getName())
.build();
}
public static ConstructorDeclaration createDefinitionConstructor(VariableRef[] properties) {
return ConstructorDeclaration.Builder.builder()
.modifiers(CodeModifier.PUBLIC)
.parameters(Arrays.stream(properties)
.map(ref -> Factories.parameter(ref.getType(), ref.getName()))
.collect(Collectors.toList()))
.body(CodeSource.fromIterable(Arrays.stream(properties)
.map(Example::defineFieldValueAsVariableValue)
.collect(Collectors.toList())))
.build();
}
public static FieldDefinition defineFieldValueAsVariableValue(VariableRef ref) {
return Factories.setThisFieldValue(ref.getType(), ref.getName(), Factories.accessVariable(ref.getType(), ref.getName()));
}
This code is bigger than the last, but if you eventually need more fields to be defined or need to change something, it is more faster and easy to do (and the code is more organized).
We are constantly improving the way you write the code, at some point of 4.0.0
snapshots you will be able to do Factories.parameter(ref)
, Factories.accessVariable(ref)
and FieldDeclaration.Builder.builder().base(ref)
which extracts the type
and name
from VariableRef
(or type
, name
, localization
and target
from FieldRef
).
If you use some one of the generators, we heavily recommends you to have the generator process
calls far from your structure generator code, this allows you to easily switch generators.