groovy dsl——配置数据驱动 groovydsl数据配置
程序员文章站
2022-04-01 20:42:12
...
已经习惯于用json来配置一些数据,因为json能够被大多数语言支持,尤其在录入的时候,js操作非常的方便。但,仍然有些问题,从配置数据生成想要的对象,代码上仍然要做一些工作,尤其在配置数据本身具有一些规则的时候,额外的工作就更多因此尝试使用dsl的方式替换部分的数据配置。由于groovy和java无缝的互操作性,因此使用groovy作为宿主语言。
groovy的dsl有几种惯用的模式,以下采用的是 category和missing method混合的方式
配置的格式如下:
java代码最终调用的是 makeBoss('boss1'), groovy代码定位并执行 boss1 的闭包, boss闭包接受一个boss对象,在闭包内部修改 boss 数值
boss闭包执行的代码为:
这样闭包执行到 职业,成长等方法的时候,就会去调用bossObject的方法。
但由于 bossObject 是一个java 对象, 因此向它添加新方法就需要利用到groovy的动态性,也就是使用 category的方式。如 职业,成长等方法,因此代码变为:
最后要做的是 boss1 方法的动态定义,这个需要用到 missingmethod
这里假设不存在的方法调用都是boss类方法,这样 boss1方法实际上变成了 boss('boss1', closure)
需要注意的是,methodMissing的参数格式要严格书写,否则groovy不会认为是个methodMissing方法
相比原先json的配置方式,有三个优点:
缺点也有:
groovy的dsl有几种惯用的模式,以下采用的是 category和missing method混合的方式
配置的格式如下:
boss1 { 职业 "魔法师" 成长 'A', 'B', 'B' 技能 "火炎":4, "冰霜":3, "落雷":3 升级 40 增加魔力 20 }
java代码最终调用的是 makeBoss('boss1'), groovy代码定位并执行 boss1 的闭包, boss闭包接受一个boss对象,在闭包内部修改 boss 数值
boss闭包执行的代码为:
Closure boss = findBossClosure(bossName) boss.delegate = bossObject boss.call(bossObject)
这样闭包执行到 职业,成长等方法的时候,就会去调用bossObject的方法。
但由于 bossObject 是一个java 对象, 因此向它添加新方法就需要利用到groovy的动态性,也就是使用 category的方式。如 职业,成长等方法,因此代码变为:
use (BossHelper) { Closure boss = findBossClosure(bossName) boss.delegate = bossObject boss.call(bossObject) }
最后要做的是 boss1 方法的动态定义,这个需要用到 missingmethod
def methodMissing(String methodName, args) { boss(methodName, args[0] as Closure) }
这里假设不存在的方法调用都是boss类方法,这样 boss1方法实际上变成了 boss('boss1', closure)
需要注意的是,methodMissing的参数格式要严格书写,否则groovy不会认为是个methodMissing方法
相比原先json的配置方式,有三个优点:
- 1. 数据脚本化,通过使用一些简单的预定义规则,数据配置的适应性更强
- 2. 把部分逻辑从代码推向数据,从而能够使常变动的内容在配置层面处理掉,而不需要更改数据处理代码的逻辑
- 3. 动态可控,通过category的方式,动态性局限在指定的范围内,不会扩散
缺点也有:
- 1. 少了数据的处理代码,但是多写了向dsl暴露的接口和实现
- 2. 需要额外的增加脚本验证功能,我指的是想数据配置人员提供的工具
- 3. 可能会受不了诱惑而使数据配置功能过多而失控
- 4. 不得有边际效应