【发布时间】:2013-06-01 19:29:37
【问题描述】:
所以我想向 JDK 类添加方法,如 InputStream、File 等。我试图找出最好的方法是什么,但似乎有几种选择。一种方法是通过将方法添加到 Class 的 metaClass 属性中,如下所示:
InputStream.metaClass.copy = { OutputStream out ->
long total = 0
byte[] buffer = new byte[8096]
int len
while ((len = read(buffer)) >= 0) {
out.write(buffer, 0, len)
total += len
}
out.flush()
return delegate
}
另一种方法是使用这样的动态混合:
class EnhancedInputStream {
static {
InputStream.metaClass.mixin( EnhancedInputStream )
}
public InputStream copy( OutputStream out ) {
long total = 0
byte[] buffer = new byte[8096]
int len
while ((len = mixinOwner.read(buffer)) >= 0) {
out.write(buffer, 0, len)
total += len
}
out.flush()
return mixinOwner
}
}
所以第一个问题是动态 Mixins 是否会取代使用 metaClass + Closure 来创建 mixins?动态混合的示例并没有真正详细讨论我能找到的范围规则。这让我想到了下一点。
您可以在第一个使用 metaClass 的代码示例中看到,我使用委托来访问我正在向其中添加方法的类的 this 指针。使用动态 Mixins 的等效方法是什么?我发现的所有例子都是无状态的(真的毫无意义)。我发现一个例子提到了一个可以用来代替委托的特殊成员 mixinOwner。这是真的吗?
其次,您会看到我在 EnhancedInputStream 中使用了一个静态块来动态地将 mixin 添加到 InputStream。使用 metaClass 时,添加这些的最佳方法是什么?另一个带有 import 语句的静态块?
我想我真的只想要一个编译时 Mixin,我可以在 mixin 的源而不是目标上定义 @Mixin,因为我没有编写目标。喜欢
@MixinInto(File)
public class EnhancedFileMixin {
public void zip( File output ) {
// .....
}
}
但这在 Groovy 领域似乎并不存在。那么使用 metaClass 或动态 mixins 实现这一目标的最佳方法是什么?
【问题讨论】:
-
只是一个想法:使用“访问者”设计模式不是正常的做法吗?此外,您的“复制”对象让我想起了“功能”设计模式......
标签: groovy metaprogramming mixins