コマンドマップ
ふと、思いました。
class Program { static void ActionA() { Console.WriteLine("Action A."); } static void ActionB() { Console.WriteLine("Action B."); } static void ActionC() { Console.WriteLine("Action C."); } static void Main(string[] args) { do { // コマンド入力 Console.Write("Input Cmd> "); string cmd = Console.ReadLine(); switch (cmd) { case "A": // Aコマンドを実行 ActionA(); break; case "B": // Bコマンドを実行 ActionB(); break; case "C": // Cコマンドを実行 ActionC(); break; default: break; } } while (true); } }
上記のサンプルような場合、コマンド増えるごとに、判断する箇所が増えていく・・・
もっと、シンプルに簡単にならないものか?と。
シンプルかつ、簡単にできるなら、後からの追加変更とか容易だし、修正によるバグも少なくなるのでは??
という建前の元、考えてみました。
本当は、コードの量が多く汚くなりそうなんで、嫌だなって単なる我が儘です(笑)
/// <summary> /// コマンドMap /// </summary> static Dictionary<string, Action> _actionMap = new Dictionary<string, Action>(); static void Main(string[] args) { // コマンドを登録 _actionMap.Add("A", new Action(ActionA)); _actionMap.Add("B", new Action(ActionB)); _actionMap.Add("C", new Action(ActionC)); do { // コマンド入力 Console.Write("Input Cmd> "); string cmd = Console.ReadLine(); if (_actionMap.ContainsKey(cmd)) { // コマンド実行 _actionMap[cmd](); } } while (true); }
Actionは、.Net3.5で定義されているdelegateのGenericです。
戻り値なしで、引数4個までなら、デフォルトであります。
要は、コマンドと実行メソッドをDictionaryで管理し、実行時にコマンドをキーにして、実行メソッドを呼び出すという仕組み。
これで、増えた場合は、対象のメソッドを作成し、Dictionaryに追加する。消す場合は、Dictionaryの追加部分を削除するだけで、対応できる。
呼び出す部分も、増えていかず、きれいさっぱりに!(笑)
別途、専用にdelegateを定義して行えば、.Net2.0でも、戻り値ありも、引数ありも可能です。
ただし、コマンドの引数、戻り値が共通になっている必要がありますが。