Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9551

閏年判定について(可読性とともに)

$
0
0

先日、教材に記載されていた閏年判定のコードに対し、
自分なりに改善できる点があったのでアウトプットする。

boolIsLeapYear(intyear){//良い点 その1boolresult=false;//悪い点 その1if(year<=0){//良い点 その2thrownewArgumentException("Year needs to be positive.");}if(year%4==0){if(year%100==0){if(year%400==0){//悪い点 その2result=true;}}else{result=true;}}returnresult;}

なんで自作するの?

そもそもの前提から覆すが、最近の高級言語では、閏年判定のライブラリはあらかじめ用意されている。
これらを知らずして自作することは、よほどの事情がない限り、許されないだろう。
自作が許されない理由は明白である。第一に品質であり、第二に品質を担保するまでの工数である。

自作メソッドと公式ライブラリでは使用実績及び、品質はどちらが上であろうか。間違いなく後者である。
また、自作メソッドの品質を担保するまでにどの程度の工数を必要とするであろう。ライブラリならば0である。

がむしゃらに作ることをやめ、同じことをするメソッドがないかを調べることはとても大切なことである。

それでも自作する場合

教材のソースコードの良い点、悪い点を見ていく。

良い点

その1 メソッド名

名前は良いだろう。
どういう場合にtrueが返ってくるのかをメソッド名のみで判断することができる。
bool値を返すメソッドの命名規則は、いろんな記事があるので、ググって参考にしてほしい。

その2 引数検査あり

引数の検査を行っており、適切な例外を投げている。
エラーアトミック性に努めているといえるだろう。

悪い点

その1 無駄なローカル変数

メソッドの一行目でresult変数を宣言しているが、不要である。
本メソッドの返り値はbool値であるため、return true; もしくは return false;を直接書けばよい。
仮に変数を設けるとしても、変数のスコープは可能な限り狭くすべきだ。

その2 if文のネスト数

このメソッドの最大の問題点である。
if文が3つ続いており、そのあとにelseが来ている。このelseはどのifに対するelseだろう。
当然、よく読めば理解できる。しかし、あなたは少なからず考えることを強制されたであろう。

ここで、閏年となる条件式を見てみよう。

4で割り切れる。 かつ 100で割り切れない。
もしくは
400で割り切れる。

そのままif文にしてみよう。

if((year%4==0&&year%100!=0)||year%400==0){returntrue;}else{returnfalse;}

なぜ、わざわざ複雑にするのだろうか。

改善の余地はまだある。

return文の多用

if文の条件式の構造がわかりずらい。return文を多用することで、条件式を分解しよう。
return文の多用はいいこと尽くしである。
以下の説明は、恥ずかしながら適切とは言えない。ぜひ最後のソースコードと一緒に読んでほしい。

if文内の条件式の構造を省略すると (A and B) or C となる。
①(A and B) を満たした時点で閏年が確定するため、trueを返す。
②Cを満たす場合も、閏年のため、trueを返す。
③上記に当てはまらない場合、閏年ではない。よって、falseを返す。

①と②は or の関係であるが、①を満たす場合はtrueを返し、①を満たさない場合は②に処理が流れる。
よって、処理が②に移っている時点で、①を満たしていないという暗黙の条件記載が存在するのである。
①を満たせばtrue、①を満たさずとも②を満たせばtrueというor条件をorの記載なしに実現できるのだ。

③も同様である。処理が③に移っている時点で①、②の両方とも満たしていないことになる。
よって、③にいる時点で閏年ではない。else句を記載することなく、elseのような処理を実現できるのだ。

これは、プログラムは上から順に処理されるという大前提と、return文による暗黙の条件記載が見事にかみ合っているのだ。

おまけ

{}内が1行ならば、省略することができる。(C#)

boolIsLeapYear(intyear){if(year<=0)thrownewArgumentException("Year needs to be positive.");if(year%4==0&&year%100!=0)//1returntrue;if(year%400==0)//2returntrue;returnfalse;//3}

可読性は十分だろう。上から流れるように読める。
あなたはこのプログラムを見るときに考えることを強制されるだろうか。

所感

美しさを求めるだけはNGなので、大儀を見失わないこと。
小さいプログラムならば効果は薄いかもしれないが、複雑な業務ロジックでは小さなことが効いてくる。


Viewing all articles
Browse latest Browse all 9551

Trending Articles