Vous avez probablement déjà entendu parler de Kotlin DSL et essayé des bibliothèques telles que Anko pour accélérer votre développement Android. Gradle 5.0, récemment publié, inclut le Gradle Kotlin DSL v1.0, qui est maintenant prêt pour une utilisation généralisée. Les utilisations de Kotlin DSL peuvent également être trouvées dans un framework Web tel que Ktor.
Dans cette Pépite #3, je veux vous montrer un exemple sur comment écrire un Builder avec Kotlin DSL.
Imaginez une data class Beer, qui contient des propriétés comme le nom, le degré d’alcool, le style et la région d’une bière. La data class Region contient tout simplement le nom de la ville et le nom du pays d’où la bière est produite :
data class Beer( val name: String, val strength: Float, val style: String, val region: Region ) data class Region( val city: String, val country: String )
La partie code DSL contient :
- Une class
BeerBuilder
- Une class
RegionBuilder
- Et une fonction qui prend un lambda avec receiver (
BeerBuilder.() -> Unit
) en paramètre et produit l’objetBeer
en retour
class BeerBuilder() { var name = "" var strength = 0f var style = "" var region = region { city = "" country = "" } fun region(init: RegionBuilder.() -> Unit) = RegionBuilder().apply(init).build() fun build() = Beer(name, strength, style, region) } class RegionBuilder() { var city = "" var country = "" fun build() = Region(city, country) } fun beer(init: BeerBuilder.() -> Unit) = BeerBuilder().apply(init).build()
Et, grâce à BeerDSL qu’on vient de créer, nous pouvons maintenant instancier un objet Beer avec le DSL :
val brooklynLager = beer { name = "Brooklyn Lager" strength = 5.2f style = "American Amber Lager" region = region { city = "Brooklyn" country = "USA" } }
Le résultat est expressif et extrêmement lisible, mais que se passe-t-il si nous voulons avoir des champs obligatoires dans notre DSL builder ? Et comment s’assurer que notre DSL est type safe ? Une prochaine pépite vous parlera de ces sujets, notamment l’annotation @DslMarker qui fait partie de kotlin-stdlib.