Web/DB プログラミング徹底解説

ホーム > ソフトウェア開発に関する考察 > 欠陥の検出は出来る限りコンパイル時に行う

欠陥の検出は出来る限りコンパイル時に行う

例えば、二種類の値のみを取りうるパラメータを受け取る関数を設計することを考えてみましょう。

具体的に例をあげたほうがわかりやすいので、例えば性別を受け取るとしましょう。Male (男) と Female (女) の二種類を受け取るとします。

その場合、あるオブジェクトに性別を設定する SetGender というメソッドを実装するとします。

このとき、どのようにメソッドのパラメータを与えればよいでしょうか。

ひとつめは、性別の値を文字列でとる方法があります。


	public void SetGender( string s ) {

		if( s == null 
		|| ( s.ToUpper() != "MALE" && s.ToUpper() != "FEMALE" ) ) {
			// 例外を投げる
			return;
		} 	

		// 内部変数にセット
		_val = s;
			
	}

引数を文字列で受け取っています。

このような実装に様々な問題があることがお分りでしょうか。

文字列は様々な値を取る可能性がありますから、メソッドの内部で始めにその値を検証しなければなりません。 値を検証するためだけに、ToUpper() メソッドを呼び出すなどの必要があり、文字列の比較をするためのコストもかかります。

また、呼び出す時に、何を渡せばよいか明確ではありません。つまり、後でこのメソッドを使う人が、 引数にどのような値をとるか分かりません。男を表すための値は、 "otoko" という文字かもしれませんし、"M" という文字かもしれません。

さらに悪いことに、この関数の呼び出しを正しく行っているかどうか、ということは実行時にしか検出できません。

例えば、このメソッドは "MALE" か "FEMALE" という値しか受け取らないのに、"M" と "F" を渡している箇所があったとします。 この誤りを検出できるのは、実行時のみなのです。

テストが十分に全体をカバーしており、リリース前にその間違いを検出できれば幸運です。 しかし現実には、テストだけで全ての欠陥を検出することは不可能であり、たいていは、非常に重要なデモを行うような時に、その不具合が顔を出してくるものです。

まとめると、簡単にパッと考えるだけでも、この実装には次の問題が含まれていることになります。

  • 実行効率が悪い
  • 呼び出し方が不明確で混乱を招く
  • 間違っていても検出できない

これをどのように解決したらよいでしょうか?

実はこれには非常に簡単な解決策があります。

次のような型を定義すればよいのです。

enum Gender {
	Male,
	Female
}

そして、メソッドの引数にそれを設定します。


	public void SetGender( Gender g ) {

		// 内部変数にセット
		_val = g;
			
	}

このようにすれば、引数の g は Gender.Male または Gender.Female しか取りえませんから、 使い方及び値を間違えていれば、コンパイル時にコンパイラがそれを指摘してくれます。 実行時まで不具合の検出を先延ばしされることはありません。

この点は品質向上のために、非常に重要なポイントです。

また、他の開発者がこのメソッドを使う場合も、enum の定義を見れば Male, Female のいずれかの値を渡せばよいことは明確であり、 開発時間の短縮が期待できます。

さらに、もし Male のみをセットしたい場合等、値のチェックをする場合も enum の値を比較するだけですから、 文字列の比較を実行するよりずっとコストは安く済みます。(というか int ですから最安値といって良いでしょう)

このようにパラメータの設計ひとつとっても、ちょっとしたことで大きく品質に関わってくるものです。

しかし・・・ 私はこのような実装をしている時に、「柔軟性がない」 という理由で、上記の例で言えば string 方式の実装方法に書き直しを迫られたことがあります。(もちろんマイクロソフトで、ではありません。マイクロソフトでは当然上の Gender 方式です。) 「メソッドは string によって、あらゆる値を渡せるほうが柔軟性があり優れている」 というのです。

私は上述の点を指摘しましたが、「それは好みの問題だ」 と一蹴されてしまいました。 「単なる好み」以上の理由があることは上述の通りなのですが。

しかも、そもそも受け取る値に制限があるのですから、パラメータの渡し方をあいまいにする事によって「柔軟性」とやらを向上できる理由がありません。

「無学者論に負けず」 とはよく言ったもので、何も考えていない人にはこうした理屈が通じないこともあるようです。