if(stringVariable.equals("")) について
次のJavaコードはどう改良できる?:ITpro
について、いろいろな議論があったのですね。こんなに盛り上がっていたの、知りませんでした。
読む中で、いろいろな立場の議論があり、自分なりにまとめてみたいと思ったのが、このエントリを書いた目的です。
議論されている立場を以下の3種類に分類しました。
- インターフェースを提供するクラスまたはコンポーネント
- インターフェースを通じてクラスを利用するソフトウェア
- ソフトウェアを利用する顧客
以下、これらを逆に見ていきます。
ソフトウェアを利用する顧客から見たら?
サービスの継続性、安全性が重要だと思います。
サービスの継続性という観点からみると、nullであってもなくても利用するサービスに影響ないのであれば、変に例外が発生してサービスが受けられなくなると困る。
例えば、「XX情報は取得できなかった」と表示すればよい場合もある。
サービスの安全性という観点からみると、安全に倒したことにより、間違った処理をしてしまうのであれば、実施されては困る。
「何事もなく」誤った処理が行われては困るわけです。
ここで、別のソフトウェアにサービスを提供する「クラス」や「コンポーネント」がとるべき判断と、顧客にサービスを提供する「アプリケーション」がとるべき判断は切り分けて考えるべきだと考えており、顧客に対するサービスの継続性や安全性を考えるのは、「アプリケーション」側の判断と切り分けています。アプリケーション側では、利用するインターフェース(「クラス」や「コンポーネント」)から判断に必要な情報が返ってくることが望ましいと考えます。この点で、個々のインターフェースからは例外なり、エラーコードかもしれんが、何か返してほしい。ちょっと議論が混乱しました。「何か返してほしい」と望むのは「インターフェースを通じてクラスを利用するソフトウェア」ですね。
この点で、きしださんとは少し意見が異なります。シャワーヘッドで説明されていることから、プログラムを顧客視点で眺めているように解釈したのですが、単なるメタファでしたらすみません。
インターフェースを通じてクラスを利用するソフトウェアから見たら?
※クラス外から文字列をもらう想定で記述
契約が明確にし、明示することが大切だと感じます。
nullを許容するのか、しないのか。その場合のふるまいはどうなるのか?
クラス内でどう実装するかなんてどうでもよくて、JavaDoc等で示されているべきだし、もし許容しないのであればできるだけ早いタイミングで「落としてあげる」必要があると思います。
ちょっと余談です。保守開発時に、インターフェースのIN/OUTが変わらないために、「インターフェースが変わらないので結合テストしません」などと言い切ってしまうことがあります。見た目の工数を減らしたい場合や、スケジュールを短縮できるのではないかと考えてしまった場合などにこういうことをしてしまいます。例外の発生条件も含め、JavaDocに記載すべき事項が変われば、「インターフェースは変わる」ことになるので、これは誤りですね。
インターフェースを提供するクラスまたはコンポーネントから見たら?
わかりやすさ、メンテナンスのしやすさ、つまりバグの入りにくさが重要だと考えます。
「美しさ」はわかりやすさを犠牲にしない範囲でお願いします。
プログラム上の「意味」が理解できるほうがよい
フルートレッスン戦争記:Javaのサイズ0文字列判定に書かれている、以下の内容に同意です。
左辺と右辺の意識は必要だと思いますね。これでは比較結果が同じでも、文の主語が目的語が完全に逆転してしまいます。
「主語.equals(目的語)」 となる、
s.equals("")
を支持します。説明しやすいし、パッと見で理解できます。コードレビューでの説明のしやすさを想像してみてください。
もちろん、これは「書く」側の理論です。あるプログラムの保守を任された場合には、おかざきさんが書かれているように、理解してメンテナンスできる知識は必要ですね。
null の扱いはプログラム内で明示されているべき
null がダメなら、冒頭かどこか早いタイミングでnullチェックで落とすべき。これは
#"".equals(stringVariable) は改悪だろうの改良案3ですね。
null が OK で、分岐でどちらかの処理が行われるべきなのであれば、
if (s == null)
などと明示したほうがわかりやすい。
ついで:プログラムを修正する際に意図を変えないこと
発端となった ITpro の記事は、別の話を同列に判断しているので、違和感があります。
従って、これはひどい問題 - しんさんの出張所 はてな編で書かれている、
わはは。改良じゃなくて別の意味になってるじゃねーか。
に激しく同意であります。