あぁ=

私は安易にコンストラクタ内で文字列を空文字列に初期化したりする
プログラマーが大嫌いです。あれって問題を隠蔽しかねないですよね?
あぁ〜このことを理解して欲しい。


そう思ってカキコします。


例えば下記のような仕様があった場合にあなたはどういった
ソースコードを書きますか?

<問題>
あるオブジェクト(logic)からgetData()メソッドを呼び出して
値を取得し、5桁〜6桁で切り出して返却して下さい。
例:getData()の値がABCDEFだった場合はEFです。
  ABCDEF→EF

String value = logic.getData();

この問題であなたは下記のどちらが正しい解答だと思いますか?

①
	String value = logic.getData();
	return value.substring(4, 6);

②
	String value = logic.getData();
	if (value != null && value.length() > 5) {
		return value.substring(4, 6);
	} else {
		return "";
	}

単純に答えると①のようになりますよね。


String value = logic.getData();
return value.substring(4, 6);


しかし、このソースは暗黙的には
logic.getData()がnullを返さないし、文字列の長さが6桁以上あること
が条件になっています。


そして、その条件を満たさなかった場合はExceptionを発生しますよってこと
ソースコードは言っています。


このことを認識しているかしていないかはプログラマのレベルですよね。


じゃ〜認識したプログラマが②のように答えたとしましょう。


String value = logic.getData();
if (value != null && value.length() > 5) {
return value.substring(4, 6);
} else {
return "";
}


このソースは暗黙的になにを言っているかというと
logic.getData()がnullを返そうが、文字列の長さが6桁に満たないとしても
Exceptionは発生しないようにしています。


そして、logic.getData()がnullか長さが6桁に満たない場合は空文字列オブジェクトを返却します。
と言っていますよね。


ん〜一見言い感じに聞こえます。


はたして最適な解は②でしょうか?
どちらかというと私としては①の方がベターだと思います。


なぜなら、②は勝手に仕様を変えていますし、
問題を隠蔽しかねないと思うからです。


この仕様策定者は本当にnullだった場合に空文字列が欲しかったのでしょうか?
大体の場合はそこまで考えていないということでしょう。


そうです。
この問題の解答は①でもなく②でもないのです。


最適な解はこれだけでは判断できないことを悟り問題点を含めて
仕様策定者に確認することが必要です。
(仕様策定者がそれを明記していない認識していないのも問題ですけどね。)


いままでの経験では安易に②を選択して開発する人が大勢います。
②の選択をした場合にその場合はバグだからエラーにする・ログ出力する・他の値で返却する
仕様が実は必要だったのかもしれません。


このような勝手に空文字列にしてエラーが出ないようにした場合にあとの業務工程で
なんでこのデータ空なのってことになります。
この種のデータバグはなかなか見つかりにくいです。


この例でわかる通り安易にコンストラクタで文字列を空文字列で初期化したりするな!
すべてのソースに意味があるんだよ!って思ってるんです。
ぬるぽで落ちるとか言ってんじゃねぇ〜よ。と


まとまりのない文章になりましたが、
わかっていただけるひといるだろうか・・・