文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
1.7 委托模式
委托模式(Delegation Pattern) 对象行为(公共方法)由委托的一个或多个对象实现。
Groovy 还允许使用委托模式的传统方式,比如 用委托代替继承 。
1.7.1 利用 ExpandoMetaClass 实现委托模式
groovy.lang.ExpandoMetaClass 允许通过库封装来使用该模式。这能让 Groovy 效仿 Ruby 语言所用的类似库。
考虑下面这个库类:
class Delegator {
private targetClass
private delegate
Delegator(targetClass, delegate) {
this.targetClass = targetClass
this.delegate = delegate
}
def delegate(String methodName) {
delegate(methodName, methodName)
}
def delegate(String methodName, String asMethodName) {
targetClass.metaClass."$asMethodName" = delegate.&"$methodName"
}
def delegateAll(String[] names) {
names.each { delegate(it) }
}
def delegateAll(Map names) {
names.each { k, v -> delegate(k, v) }
}
def delegateAll() {
delegate.class.methods*.name.each { delegate(it) }
}
}
将它放在类路径中,可以像上例所示的那样动态地应用委托模式。首先假设我们有以下这些类:
class Person {
String name
}
class MortgageLender {
def borrowAmount(amount) {
"borrow \\$$amount"
}
def borrowFor(thing) {
"buy \\$thing"
}
}
def lender = new MortgageLender()
def delegator = new Delegator(Person, lender)
可以使用 delegator
自动地从 lender
对象处借调方法来扩展 Person
类。我们可以照原样借调方法,也可以对方法改名。
delegator.delegate 'borrowFor'
delegator.delegate 'borrowAmount', 'getMoney'
def p = new Person()
println p.borrowFor('present') // => buy present
println p.getMoney(50)
上述代码中的第一行中,通过委托给 lender
对象,为 Person
类添加了 borrowFor
方法。第二行中,通过委托给 lender
对象的 borrowAmount
方法,为 Person
类添加了一个 getMoney
方法。
另外,我们还可以借调多个方法:
delegator.delegateAll 'borrowFor', 'borrowAmount'
这会将两种方法都添加到 Person
类上。
或者,有时我们会需要所有方法:
delegator.delegateAll()
从而使 Person
类能够使用委托对象中的所有方法。
另外,可以利用映射标记重新命名多个方法:
delegator.delegateAll borrowAmount:'getMoney', borrowFor:'getThing'
1.7.2 利用 @Delegate
标记实现委托模式
从 1.6 版开始,可以使用内建的基于 AST 变换的委托模式。
委托可以变得更简单:
class Person {
def name
@Delegate MortgageLender mortgageLender = new MortgageLender()
}
class MortgageLender {
def borrowAmount(amount) {
"borrow \\$$amount"
}
def borrowFor(thing) {
"buy $thing"
}
}
def p = new Person()
assert "buy present" == p.borrowFor('present')
assert "borrow \\$50" == p.borrowAmount(50)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论