Implementing a Rules DSL
[ 284 ]
assert account.balance == 100.00
def shell = new GroovyShell(binding)
shell.evaluate(
""" reward {
apply {
if (account.active && monthSpend > 10.00)
credit 5.00
}
}
"""
)
assert account.balance == 105.00
Here we embed an account object in the binding, along with a calculated value
for the user's monthly spend to date. We have also introduced a shortcut for the
account credit method, by including a closure called credit, which is taken
from the address of the Account.credit method.
Another useful technique is to predetermine states and boolean conditions, and
store them in appropriately named binding variables. For the rewards DSL, some
common tests that we might need to make are whether the account is active,
and whether the minimum spending threshold has been reached. Setting these
conditions into binding variables will further improve the readability of the DSL.
reward {
apply {
if (ACTIVE && REWARD_THRESHOLD_EXCEEDED)
credit 5.00
}
}
Storing and communicating results
Capturing the values of variables set in the DSL can also be done through the
binding. The delegate is set by each calling closure, so any variables defined in the
scope of the DSL blocks will be available as binding variables to the calling closures.
def binding = new Binding()
binding.outerBlock = { closure ->
closure.delegate = delegate
closure()
println "outerBlock: " + binding.message
http://www.ebook3000.com