love! LOVEHINA - love2hina.net


カテゴリー

アーカイブ
2010/06/12 SEのプログラムスキルレベルアップ!?

作成者: カテゴリー: 未分類

今日はちょっと愚痴混じりのまじめな話。

今の仕事は別の会社が作成したプログラムの改修・保守をしているのですが、
それが改修を行うと、必ず潜在不良が見つかるという品質・保守性の悪さに工数は爆発的に増加。

原因は、元々の担当者が今まで業務プログラムしか経験がなかったのが、
突然一般パッケージソフトを担当したことかと思っています。
そこで、こんなことを避けるためのいくつかのポイントを挙げてみようと思います。

業務担当から、他の担当(基盤や一般パッケージ)を担当することになったアナタ、必見です(大嘘)

ポイント1 – 関数の戻り値はエラーコードを返すものじゃない

業務でよく使用される COBOL(85) は、エラーがあった場合、
プログラムの戻り値としてエラーコードを返すほか通知方法がありませんでした。
(※COBOL 2002では、構造化例外処理がサポートされましたので、厳密には今は違います。
ただ、COBOLで存在するプログラムは古くに作られたものをそのままストコンする場合が多いので)

COBOLの考え方をそのまま踏襲すると、関数は戻り値がエラーコードを示す、ということが多いのですが、
以下のようにその部品を使う呼び出し元の制御処理が煩雑で、処理フローが読みづらくなります。

int Proc(const char * arg)
{
   int intResult;

// 関数を呼ぶよ! intResult = funcA(arg); if (intResult != S_OK) { return intResult; }
// 次も! intResult = funcB(); if (intResult != S_OK) { return intResult; }
return S_OK; }
int funcA(const char * arg) { // 引数は正しい? if (arg == NULL) { return E_POINTER; }
// 何か処理…
return S_OK; }

C++やJava、Visual Basicなど最近の言語には構造化例外処理という仕組みがあります。
システムエラーとして扱うべきものは、この例外というものを使うようすべきです。

void Proc(const char * arg)
{

funcA(arg); funcB(); }
void funcA(const char * arg) { // 引数は正しい? if (arg == NULL) { throw clsNullPointerException(); }
// 何か処理… }

結果的に、関数の戻り値は正常値しか扱わなくなり、インターフェースがわかりやすくなります。
また、呼び出し側も条件分岐がなくなり、これは単体テスト工数の削減に大きく寄与します!

※注 サンプルコードは色々端折っています。