サイクロマティック複雑度をあげずに分岐の多いswitch~caseを処理する方策
ことのはじまり
コマンドを読み込んで処理を実行するプログラムを作っていたのですが、コマンドを読んで処理を分岐する部分をswitch~caseで実装したところ、分岐が多すぎてVisualStudioでコードメトリクスを算出したときにサイクロマティック複雑度が50を超えてしまいました。
コマンド分岐部分なので無視してもよかったのですが、あまり美しくないのでもう少し良い方策がないか悩んだ結果、コードチェック上はサイクロマティック複雑度を上げずに書けたので、その方法を記載します。
(※あくまでコードチェックツール上のサイクロマティック複雑度を減らせるというだけで、実際的な意味では分岐は減っていないです。)
対応方法
まず、もとのコードは下記のような状態とします。
switch(commandString){
case "commandA":
stringResult = commandAExec(arg1,arg2);
break;
case "commandB":
doubleResult = commandBExec(arg1);
break;
//以下同様の分岐が続く...
}
string commandAExec (string arg1,double arg2){
//CommandAの処理
//・・・
return stringResult;
}
double commandBExec(string arg1){
//CommandBの処理
//・・・
return doubleResult;
}
//以下同様のメソッド多数...
//・・・
これに対して、コマンドごとに呼び出されるメソッドのデリゲートを作成してディクショナリに格納し、switchのかわりにディクショナリのキーを使って呼び出します。
1.分岐先のメソッドの戻り値と引数を一本化する
DTOを作成して、すべての分岐先のメソッドの引数と戻り値を一本化します。
class CommandArgDto{
public string FieldArg1 {get;set;}
public double FieldArg2 {get;set;}
//必要なフィールドを定義する
}
class CommandResultDto{
public string FieldResult1 {get;set;}
public double FieldResult2 {get;set;}
//必要なフィールドを定義する
}
CommandResultDto commandAExec(CommandArgDto args){
CommadnResultDto result;
//コマンドAの処理
//・・・
//・・・
return result;
}
CommandResultDto commandBExec(CommandArgDto args){
CommadnResultDto result;
//コマンドBの処理
//・・・
//・・・
return result;
}
2.一本化したメソッドを取り扱うデリゲートを定義する
delegate CommandResultDto CommandDelegate(CommandArgDto args);
3.デリゲートを格納するディクショナリを作成し、中身を詰める。
var commandDic = New Dictionary<string,CommandDelegate>();
//コマンドとメソッドの組み合わせをディクショナリに格納する
commandDic.Add("commandA",commandAExec);
commandDic.Add("commandB",commandBExec);
//必要な組み合わせを追加
4.switchの代わりにディクショナリにキーを渡して呼び出す
commandArgDto args;
CommandResultDto result;
//argsに引数を設定する
//・・・
//キーが存在するかどうかは先にチェックする
if (commandDic.ContainsKey(commandString)){
CommandDelegate command = commandDic[commandString];
result = command(args);
}
そうするとあら不思議、switch分岐がないのでサイクロマティック複雑度があがらなくなりました。
実際にデバッグするときにどちらのほうがわかり易いかと言われると素直にswitchで分岐してあったほうがいいような気もするので微妙なところです。
Author And Source
この問題について(サイクロマティック複雑度をあげずに分岐の多いswitch~caseを処理する方策), 我々は、より多くの情報をここで見つけました https://qiita.com/kn2018/items/d4602def874c1e2e2fb5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .