Groovy 使用 use 关键字进行混入

考虑一个程序从外部设备读取两个整数,然后将它们加在一起,并且回写结果,读和写都是字符串处理;但是加法操作是整数相加,你不能这样写:write( read() + read() )因为这样的结果为在字符串上调用 plus 方法来连接另外一个字符串。

而不是进行整数加法运算。

Groovy 提供了 use 方法(像大多数 groovy 程序员,我们更喜欢叫做 use 关键字,但严格意义上应该叫它是一个方法,这是 groovy 增加到 java.lang.Object 上的方法),这允许你扩展一个类的可用实例方法,这样的用法被叫做类别(category),在我们的例子中,我们能在字符串上扩展 plus 方法来得到一个所需的像 Perl 的行为:[code]use(StringCalculationCategory) {

write( read() + read() )

}
[/code]一个 category 是一个类,这个类包含一组静态方法(叫做 category 方法),use 关键字使这些方法在方法的第一个参数的类上可以作为实例方法使用:[code]class StringCalculationCategory {

static String plus(String se lf, String operand) {

// implementation

}

}
[/code]由于 self 是第一个参数,plus(operand)方法现在在 String 类上是可用的(或者覆盖)。

列表 7.24 显示了一个完整的例子,它可靠的实现了这样的需要,使字符串进行真正的数字相加,而不是一般的字符串拼接。

Category 的用法被限制在闭包体内和当前线程上,这样改变之后不会在全局可视,避免

了无意识的副作用。

通过这本书的语言基础部分,你已经看到 groovy 增加了新的方法到存在的类,整个 GDK

的实现都是增加到已经存在的 JDK 类上的新方法,use 方法允许任何 groovy 程序员在他们

自己的代码中使用相同的策略。

Category 的使用有多个目的:

 提供专门用途的方法,就像你看到的 StringCalculat ionCategory 一样,计算方法有相同的接受类并且也许覆盖了已经存在的行为,覆盖操作符方法是一个特例。

 为已经存在的类库提供附加的方法,有效的解决了类库中没有完成的类的问题。

 为 不 同 的 接 受 者 提 供 一 组 方 法 , 使 他 们 组 合 工 作 —— 例 如 , 一 个 在 java. io.OutputStream 上的新的 encryptedWrite 方法和在 java. io.InputStream 上的 encryptedRead 方法。

 实现了 java 的装饰模式,但是不用编写许多麻烦的中继方法。

 分离一个过度的大类为一个核心类和多方面的类别(category),这样在需要的时候使 category 和核心类一起使用,注意,use 能接受任意多个 category 类。

在一个 category 方法被指派给 Object 的时候,这个方法在所有对象上都是可用的—— 也就是说,在哪里都可以用这个方法。这是美好的万能方法如日志,打印,持久化等等,例如,你已经知道每个对象都需要持久化:[code]class PersistenceCategory {

static void save (Object self) {

// whatever you do to store ‘self’ goes here

}

}

use (PersistenceCategory) {

save ()

}
[/code]与 Object 相反,一个更小范围的应用也许更有利,如所有的 Collection 类或者你自己的业务对象(如果他们共享通用的接口)。

注意你可以为 use 传递许多 categroy 类,这些类通过逗号进行分隔,或者将这些category 类放在一个 list 中。use (ACategory, BCategory, CCategory) {}现在,你应该对 groovy 的强大特性有一些想法了,它们在第一次阅读的时候让人印象 深刻,但在真实的应用中使用它们的时候,记住它们在早期提到的价值,这样你不会仅仅由于不熟悉特性和模式而错过一些优雅的代码,不久之后,你将熟练起来这样在你被迫回到 java 中的时候你将想念它们,好的消息是在 java 中是容易使用 groovy 的,我们将在 11 章进行探讨。

Category 类在闭包中的使用是一个 groovy 能提供的特性,因为他是元程序的概念。