我的示例是使用Koshuke args4j's @Option
注释完成的,但同样适用于任何其他方法注释。只是为了澄清,这个注释可以与字段或setter一起使用。
它的工作原理如下:
class AnOptionExample {
@Option(name = '-text')
String text
}
测试用例:
def 'recognises option from simple object'() {
given:
def options = new AnOptionExample()
def parser = new CmdLineParser(options)
when:
parser.parseArgument('-text=whatever')
then:
options.text == 'whatever'
}
现在假设我想在接口级别上进行注释,然后重新使用@Option
定义以及具有多种继承,这将允许我们使用不同的选项集的不同接口(简化)示例):
interface Credentials {
@Option(name = '-username')
void setUsername(String username)
@Option(name = '-password')
void setPassword(String username)
String getUsername()
String getPassword()
}
class CredentialsImpl implements Credentials {
String username
String password
}
显示失败的测试用例:
def 'does not recognise option from interface'() {
given:
def options = new CredentialsImpl()
def parser = new CmdLineParser(options)
when:
parser.parseArgument('-username=John', '-password=qwerty123')
then:
def ex = thrown(CmdLineException)
ex.message == '"-username=John" is not a valid option'
}
嗯,接口的方法注释不是继承的。足够公平 - 这是Java方式,但Groovy怎么样?以下是一些希望:
class SomeOptionsWithDelegate {
@Delegate(methodAnnotations = true)
final Credentials credentials = new CredentialsImpl()
@Option(name = '-url')
String url
}
表示奇怪的测试用例:
def 'does recognise option from interface via @Delegate'() {
given:
def options = new SomeOptionsWithDelegate()
def parser = new CmdLineParser(options)
when:
parser.parseArgument('-username=John', '-password=qwerty123', '-url=http://auth.plop.com')
then:
with(options) {
username == 'John'
password == 'qwerty123'
url == 'http://auth.plop.com'
}
}
令人惊讶的是@Delegate(methodAnnotations = true)
仍然有效,尽管完成委托的对象实例没有注释 - 只有Credentials
接口有它们。并且没有方法注释继承...哦等等,实际上这就是重点。这似乎是个小故障。为什么@Delegate
能够在CredentialsImpl
未继承的情况下获取接口级别上声明的注释?
另一方面,我希望具有这样的行为作为一个功能,所以我不需要在这里使用委托,而是像:
@InheritInterfaceMethodAnnotations
class SomeOptionsViaInterface implements Credentials {
String username
String password
@Option(name = '-url')
String url
}
上述示例的明显相关测试用例将以与第二个示例相同的方式失败。因此问题是:有没有像我编写的虚构注释 - @InheritInterfaceMethodAnnotations
可用?
可以实现考虑@Delegate
故障。因为它似乎是有用的功能,也许有人已经做到了。如果没有,欢迎任何建议如何自行实施。
答案 0 :(得分:0)
你应该研究traits他们是处理这种情况的Groovy方式。它有点像扩展一个类,但你可以根据自己的需要使用尽可能多的特性。有方法重叠的规则,以及确定调用哪种特征的方法的方法。您的注释也应该有效。
?
它们也可以在运行时添加到对象中
trait Credentials {
String username
@Option(name = '-username')
void setUsername(String aUsername){
username = aUsername}
@Option(name = '-password')
abstract void setPassword(String username)
String getUsername() {return username}
abstract String getPassword()
}
class CredentialsImpl implements Credentials {
String password
@Option(name = '-password')
void setPassword(String password){ this.password = password}
String getPassword() { password }
}