演化架构和紧急设计: 使用 Groovy 构建 DSL
2010-10-09 08:12:32 来源:WEB开发网这个 categories 类包括三个 Integer 新方法:getFromToday()、getAm() 和 getPm()。注意,这些事实上是新属性,而不是方法,在这我之所以说是新属性,是和 Groovy 处理方法调用的方式有关。当您调用一个没有参数的 Groovy 方法时,您必须使用一对空括号调用它,这使得 Groovy 可以分清一个属性访问和一个方法调用之间的区别。如果我将其扩展作为方法,我的 DSL 将需要调用 am 和 pm 扩展作为 5.pm(),这会影响 DSL 的阅读性。我使用 DSL 一个最主要的原因是增强阅读性,因此我想要丢弃额外的杂乱语法。在 Groovy 中您也可以通过创建扩展作为属性进行这一操作,声明属性的语法和 Java 语言中的 get/set 方法对是一样的 — 但是您可以在没有参数的情况下调用它们。
在这个 DSL 中,测量单位是小时,这意味着我需要为 3.pm 返回 15。在构建以数量为特性的 DSL 时,您需要确定您的单位,并将它们添加到 DSL(可选)使其更可读。记住我将使用 DSL 来捕获一个领域惯用模式,这意味这非程序员也可以阅读。
现在,您已经看到了在日历 DSL 中如何实现时间,Appointment 类在清单 5 中显示,简单易懂:
清单 5. Appointment 类
class Appointment {
def name;
def location;
def date;
def startTime;
def endTime;
Appointment(apptName) {
name = apptName
date = Calendar.instance
}
def at(loc) {
location = loc
this
}
def formatTime(time) {
time > 12 ? "${time - 12} PM" : "${time} AM"
}
def getStartTime() {
formatTime(startTime)
}
def getEndTime() {
formatTime(endTime)
}
def from(start_time) {
startTime = start_time
date.set(Calendar.HOUR_OF_DAY, start_time)
this
}
def to(end_time) {
endTime = end_time
date.set(Calendar.HOUR_OF_DAY, end_time)
this
}
def display() {
print "Appointment: ${name}, Starts: ${formatTime(startTime)}"
if (endTime) print ", Ends: ${formatTime(endTime)}"
if (location) print ", Location: ${location}"
println()
}
}
更多精彩
赞助商链接