コマンドを決めたら不自然な設計が浮かんできた

TCP/IPサーバー機能を持つ装置制御ソフトがTCP/IP経由でコマンドを受け取ると、対応する動作を行う関数を呼び出す。このとき、関数は装置制御モジュールの最上位のオブジェクトからポインタをたどって呼び出される。つまり関数を呼び出すコードは次のような形になる。

//"DETECOTOR:CHANGEGAIN 3" という命令に応答
System->Apparatus->Detector->ChangeGain(3);

//"SPECTROSCOPY:START" という命令に応答
System->Measurement->Spectroscopy->Start();

ここではコマンドのフォーマットを 「DETECOTOR:CHANGEGAIN 3」 のように「カテゴリ:機能 引数」の形にしている。また、この例ではSystemオブジェクトのが最上位オブジェクトで、SystemはAppratusとMeasurementと言うメンバを持ち、さらにそのそれぞれがDetector、Spectroscopyというメンバを持つ。
上の例では、例えば、"DETECOTOR:CHANGEGAIN" というコマンドに対して Detector->ChangeGain() という形で関数が呼び出されている。この場合、コマンドの「カテゴリ」が「オブジェクト」に、コマンドの「機能」が「メンバ関数」に一致しているので、命令とオブジェクトの構造の整合性が取れている。

ところがコマンドを追加していくと、この整合性が崩れていることに気づくことがある。つまりカテゴリに対応するオブジェクトが必要なメンバ関数を持っていなかったり、呼び出したいメンバ関数が予想外のオブジェクトに実装されていたりといったことがある。

こういう場合は設計に不自然さが残っている可能性が高い。なぜなら、コマンド文字列は人間にとって自然な形で自由に考えることができるのに対し、プログラムのは分析不足や実装上の都合や手抜きによって不自然な設計になりやすいからだ。

今回コマンドを実装していく中でいくつか不自然な実装が見つかっている。このような不整合は分かりやすい形で要リファクタリングな箇所が浮かび上がらせてくれるので、安易にコマンドを変更して不整合を隠さずに設計の見直しに活用できればと思う。