與原版開發方式的比較

本頁將比較以 bukkit 原版的編寫方式與掛接ELD後的編寫方式。

分支指令與參數解析

假設你需要編寫如下的分支指令

  • /test say <message> - 發送訊息

  • /test calculate add <one> [two] - 計算加法,第二個數值如果不輸入則為 0

  • /test calculate minus <one> [two] - 計算減法,第二個數值如果不輸入則為 0

如果你使用原版的編寫方式,那麼其代碼將類似如下:

public class CalculateCommand implements CommandExecutor {

    private boolean showHelp(CommandSender sender){
        sender.sendMessage("/test calculate add <one> [two]");
        sender.sendMessage("/test calculate minus <one> [two]");
        sender.sendMessage("/test say <message>");
        return true;
    }

    @Override
    public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
        if (strings.length < 2) return showHelp(commandSender);
        switch (strings[0].toLowerCase(Locale.ROOT)){
            case "say":
                String message = String.join(" ", Arrays.copyOfRange(strings, 1, strings.length));
                Bukkit.broadcastMessage(commandSender.getName()+" say: "+message);
                break;
            case "calculate":
                if (strings.length < 3) return showHelp(commandSender);
                try{
                    int one = Integer.parseInt(strings[2]);
                    int two = Integer.parseInt(strings.length > 3 ? strings[3] : "0"); // 默認是 0
                    String msg;
                    switch (strings[1].toLowerCase(Locale.ROOT)){
                        case "add":
                            msg = one + " + " + two + " = " + (one + two);
                            break;
                        case "minus":
                            msg = one + " - " + two + " = " + (one - two);
                            break;
                        default:
                            return showHelp(commandSender);
                    }
                    commandSender.sendMessage(msg);
                }catch (NumberFormatException e){
                    commandSender.sendMessage("not a number!");
                }
                break;
            default:
                showHelp(commandSender);
                break;
        }

        return true;
    }
}

試想想之後如果你還有更多分支指令要加入,且每個分支指令的參數需求也不一樣,那麼在這個class內,你可能要繼續新增更多的 switch cases; 再假設一個分支指令內又有幾個分支指令, 那麼一個 switch case 內可能又要新增一個 switch ,如此往復。

以下是使用本框架所編寫的代碼。本框架採用了一個指令一個class的模式,從設計上是這樣的:

在上述的代碼當中,你應該也發現了使用本框架編寫指令時的第二個特點,也就是指令參數解析。 指令參數解析可讓你在執行指令時省略將輸入的指令參數轉變成其他實例的功夫,助你更方便的編寫指令。你也可以在本框架中註冊自己的指令參數解析,供給自己甚至他人使用。

在細分指令之後,還要把他們連接起來,形成樹狀關係。實現方式也很簡單:

就這樣,創建大型的分支指令就完成了。

YAML 文件處理

假設你有如下文件

在原版的開發環境下,你需要進行這些步驟以複製文件到插件資料夾,並使用 FileConfiguration 來的方法來獲取數值。

看上去並不像太困難和太麻煩,但我們擁有更便利的方式來助你處理文件。 本框架採用了物件映射關聯的方式處理文件,將使你在YAML的使用上變得更簡單:

從上述的 class 中,你不難看出這個 class 每一個屬性都代表了 config.yml 中的路徑,且已經定義了該屬性的類型。因此在經過註冊後,你可以直接注入並使用這個實例來直接存取 config.yml 中的所有內容。 例如:

至於註冊,也是極其簡單:

依賴注入

我相信各位寫過大型插件的人,都經常會用到這類的獲取方法

不管你使用了何種方式讓你從 Main Class 以外去獲取這三個 Manager, 有時候你都會發現 Main class 成為了獲取各種 Manager class 的一個集中管理器。在 Main class 中,你會初始化文件,指令,監聽器,也會初始各種各樣的自定義的 Manager class, 而每一個 Manager class 可能都會依賴某些在 Main class 中初始化的實例。

透過依賴注入的方式,你除了可以不經過 Main class 就能注入你的 class 所需要的依賴之外,也能在修改依賴時避免了對其他 class 的修改,提高可維護性。

以下為一個簡單的例子: 在指令中注入使用依賴注入

上面所提供的範例為本框架內的多語言文件功能,詳情可以參閱這裏

在指令中注入:

註冊:

最后更新于