需要在带注释的方法上使用方法参数

时间:2013-12-20 14:44:04

标签: java

我正在编写一个响应!time!sayHello等命令的IRC机器人。我遇到的挑战之一是解析这些命令最终得到一个长if / else包。为了解决这个大if / else翻滚的问题,我正在尝试使用注释将额外的命令添加到机器人中,这使得代码看起来更清晰,更易于维护和扩展。

看起来像这样;

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);
}

所以,我的问题是这个方法检查@CommandMessage方法是否需要4个参数,但这不是很严格,最重要的是它只在运行时检测到。太糟糕了!

我是否有办法获得带注释的方法以强制使用参数Bot bot, String channel, String sender, Command command

我知道最明显的方式是界面,因为它正是它们的设计目标,但这意味着每个@CommandMessage都有一个类,这真的太糟糕了。

2 个答案:

答案 0 :(得分:1)

我建议这样的解决方案:

public interface PluginMethod {
    void execute(Bot bot, Channel channel, Sender sender, Command command);
    String getCommand();
}

public interface Plugin {
    List<PluginMethod> getPluginMethods();
}

不像注释那么花哨,但你强制每个方法都使用4-Attribute-Interface。

答案 1 :(得分:0)

  

我有没有得到一个带注释的方法被强制使用参数Bot bot,String channel,String sender,Command command

我无法立即想到以标准方式实施此操作。然而,我通过编写使用反射和包扫描来检查这些事情的单元测试来“解决”类似的事情。

  • 获取预定义Java包中的所有类
  • 迭代所有方法
  • 如果存在@CommandMessage注释,请检查方法签名是否正确

然而,这取决于持续集成工作流程,特别是只有在所有测试成功运行时,代码的构建才会成功。