演化架构和紧急设计: 使用 Groovy 构建 DSL
2010-10-09 08:12:32 来源:WEB开发网即使您一点也不了解 Groovy,阅读 Appointment 类也没有一点问题。注意,在 Groovy 中方法的最后一行是它的返回值。这使 at()、from() 和 to()(this 方法返回值)方法的最后一行成为该类中的流畅接口调用。
categories 允许您以一种受控的方式改变现有的类。改变被严格限制在由 use() 语句定义的词典块中。然而,有时候您需要一个开放类的添加方法来扩展范围,这时候 Groovy 的 ExpandoMetaClass 就派上用场了。
通过 expando 开放类
Groovy 中最初的开放类语法仅使用 categories。然而,Groovy web 框架的构造器,Grails,发现 categories 固有的作用域限制太严格了,这导致开发了开放类另一种语法,ExpandoMetaClass。当您使用一个 expando 时,您需要访问类的元类(这是 Groovy 为您随机创建的)并向其中添加属性和方法。使用 expando 的日历示例在清单 6 中显示:
清单 6. 使用 expando 开放类的日历
def calendar = new AppointmentCalendar()
calendar.add new Appointment("Dentist")
.from(4.pm)
calendar.add new Appointment("Conference call")
.from(5.pm)
.to(6.pm)
.at("555-123-4321")
calendar.print()
清单 6 中的代码看起来和 清单 3 几乎一样,只是缺少了 categories 必须的 use 块。要实现对 Integer 的改变,您需要访问清单 7 中的元类:
清单 7. Integer 的 Expando 定义
Integer.metaClass.getAm = { ->
delegate == 12 ? 0 : delegate
}
Integer.metaClass.getPm = { ->
delegate == 12 ? 12 : delegate + 12
}
Integer.metaClass.getFromToday = { ->
def target = Calendar.instance
target.roll(Calendar.DAY_OF_MONTH, delegate)
target
}
更多精彩
赞助商链接