Java 需要注释方法上的方法参数
我正在编写一个IRC机器人,它响应像Java 需要注释方法上的方法参数,java,Java,我正在编写一个IRC机器人,它响应像这样的命令!时间,!说你好和类似的话。我遇到的一个挑战是,解析这些命令最终会得到一个很长的if/else包。为了避免if/else大崩溃的问题,我尝试使用注释向bot中添加额外的命令,这使代码看起来更干净,更易于维护和扩展 看起来是这样的, public class ExampleChatPlugin extends Plugin { @CommandMessage(command="!time") public void handleTime
这样的命令!时间
,!说你好
和类似的话。我遇到的一个挑战是,解析这些命令最终会得到一个很长的if/else包。为了避免if/else大崩溃的问题,我尝试使用注释向bot中添加额外的命令,这使代码看起来更干净,更易于维护和扩展
看起来是这样的,
public class ExampleChatPlugin extends Plugin {
@CommandMessage(command="!time")
public void handleTime(Bot bot, String channel, Command fullMessage) {
bot.sendMessage(channel, "I don't know the time :(");
}
@CommandMessage(command="!sayHello")
public void handleSayHello(Bot bot, String channel, Command fullMessage) {
bot.sendMessage(channel, "Oh, hi there.");
}
// etc...
}
所以!我在超类Plugin
中有一个消息处理方法,它确定在收到消息时调用哪个方法。这个方法在这里
public void callCommandMessages(String channel, String sender, String input) {
Command command = new Command(input);
for (Method m : this.getMethodsWithAnnotation()) {
String keyword = m.getAnnotation(CommandMessage.class).keyword();
if (keyword.isEmpty()) {
keyword = m.getName();
}
if (command.supportsKeyword(keyword)) {
if (m.getGenericParameterTypes().length < 4) {
MessagePlugin.LOG.debug("InputSelector method found for " + input + ", but this method needs to 4 arguments");
} else {
try {
m.invoke(this, channel, sender, command);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
System.out.println("Could not find: " + input);
}
public void callCommandMessages(字符串通道、字符串发送器、字符串输入){
命令=新命令(输入);
对于(方法m:this.getMethodsWithAnnotation()){
字符串关键字=m.getAnnotation(CommandMessage.class).keyword();
if(关键字.isEmpty()){
关键字=m.getName();
}
if(command.supportsKeyword(关键字)){
if(m.getGenericParameterTypes().length<4){
MessagePlugin.LOG.debug(“为“+input+”找到了InputSelector方法,但该方法需要4个参数”);
}否则{
试一试{
m、 调用(此、通道、发送方、命令);
返回;
}捕获(例外e){
e、 printStackTrace();
}
}
}
}
System.out.println(“找不到:“+输入”);
}
所以,我的问题是,这个方法检查@CommandMessage
方法是否需要4个参数,但这不是很严格,最重要的是,它只在运行时检测到。糟透了
有没有一种方法可以让一个带注释的方法强制使用参数Bot-Bot、字符串通道、字符串发送器、Command-Command
我知道最明显的方法是一个接口,因为这正是它们的设计目的,但这意味着为每个@CommandMessage
都有一个类,这也太糟糕了
有没有办法让一个带注释的方法强制使用参数Bot Bot、String channel、String sender和Command
我不能马上想到用一种标准的方式来执行这个。然而,我已经通过编写单元测试来“解决”类似的问题,单元测试通过使用反射和包扫描来检查这类事情
- 在预定义的java包中获取所有类
- 迭代所有的方法
- 如果存在
注释,请检查方法签名是否正确@CommandMessage
但是,这取决于持续集成工作流,特别是只有当所有测试都成功运行时,代码的构建才会成功。我建议这样的解决方案:
public interface PluginMethod {
void execute(Bot bot, Channel channel, Sender sender, Command command);
String getCommand();
}
public interface Plugin {
List<PluginMethod> getPluginMethods();
}
公共接口插件方法{
无效执行(Bot-Bot、Channel-Channel、Sender-Sender、Command);
字符串getCommand();
}
公共接口插件{
列出getPluginMethods();
}
没有注释那么花哨,但您强制每个方法都使用4属性接口。您能举一个您不喜欢看到的大型if/else包的例子吗?我原以为涉及注释的解决方案会过于成熟。这听起来像是注释处理器的工作(尽管它们编写起来相当复杂)。如果带注释的方法与参数列表不匹配,则启动时可能会失败。这还允许使用
映射在命令与其实现实例之间进行缓存。此外,您还可以使用ServiceLoader
机制来发现自定义插件。是的,这将是解决问题的一种完全标准的方法,但我担心的是类的大量扩展——目前在100-120个命令的范围内。还有一些命令,如!quidAdd
和!quizStart
是直接相关的,最好将它们保持在同一个类中,以便它们可以共享功能。