Keecom's Yuruyuru Outputs

興味のある事をゆる〜くアウトプットしていきます

良いコードを目指して ~テストコードを考える~

テストはどんなエンジニアの方でも必ず通る道です。

実際にテストする場合には、画面や統合開発環境上で操作・実行して結果を確認することもあれば、jUnitのようなフレームワークを利用してテストをすることもあると思います。
(余談ですが私がメインで開発していたSalesforceもテストクラスなるものが存在します)

思い返すと、既に完成したテストクラスを見て"…何でこれを比較しているんだ?"となることがありました。

便利かつヒューマンエラーを発生させないためのテストクラス自体が理解し辛くては、思わぬバグを見落としてしまう可能性もあるかもしれません。

今回は、テストの際に利用するテストコードについても、良いコードにすることができないかを書いていきたいと思います。

テストコードを利用する目的

まずはテストコードを利用する目的について考えましょう。
目的というよりはメリットという表現が正しいかもしれません。

負担を減らす

作成・改修した1つ1つの処理について都度実行し、結果を確認していくことは非常に時間がかかります。
とても効率的な作業とは言えません。
テストコードを利用することで、ほぼ一瞬にしてテストを実施し更に結果まで表示をしてくれるのです。
テストコードによって、テスト実施者の負担を減らすことができるのです。

ヒューマンエラーを無くす

テスト作業は、開発規模が大きければ大きいほど膨大なケース量が必要となります。
1日に数十〜数百のテストケースを実施していれば、小さな不具合を見落としてしまう可能性もあるでしょう。
それではテストを実施する意味がなくなってしまい、終いにはまた1からテストをやり直し、なんてことも。
テストコードを用いてテストをすれば、プログラムが値を比較してエラーを吐き出してくれるので、人間による思わぬ見落としが無くなります。
良くも悪くも、プログラムのせいということです。(笑)

テストを固定化する

既存機能を改修したときに、その機能部分しかテストをしていなかった。なんてことが原因で他の機能がデグレーションしてしまうことがあるかもしれません。
そういったことを防ぐために、テストコードで実施テストを固定化するのです。
例えばA,B,Cという機能があり、それぞれの機能のテストコードが存在するとします。
機能Bを改修した後に、機能A,B,Cのそれぞれのテストコード実施結果が問題なければリリース可能と判断する。といった具合にシステムの信頼性の一つのハードル(指標)となります。

テストコードを利用する注意点

テストコードを利用する注意点について記載していきます。

テストコードの結果だけを見ない

上記の目的・利点を鑑みると、テストを実行していればそれ以外は必要なく感じるかもしれません。
しかし、それは危ないです。
システムのコードは、要望によって改修されていくものです。
しかしテストコードというものはシステムに直接影響のあるものではないため、必ずしも仕様に沿っているとは限らないのです。
そのため、テストを実施する際には全てでなくても良いのでざっとテストコードに目を通しておくべきでしょう。

読みやすく改修のしやすいテストコードを意識する

テストコードは1度きりのものでも無ければ、手を加えることも多くあります。
そのため、テストは読みやすくかつ改修がしやすいコードにすることがベストです。
参考書に書いてありましたが、テストコードは言い換えれば仕様書だ、と。
やっと本題に辿り着いたので、ここからはテストコードの書き方に注目していきましょう!

テストコードを書くときに意識すること

テストデータの作成をメソッドで用意する

テストコードを利用する際に、実際のプログラムが問題なく動作するかを確認するためにテストデータを用意することになります。
その際に、テストコードの大部分がテストデータの用意で埋まってしまっては非常に見づらいです。
テストデータの作成は、固定データを作成するよなメソッドやパラメータに応じたデータを作るメソッドを用意し、読み解くのに必要でない情報は極力メソッドに移しましょう。
また、上記を行うことで再利用化も実現できるので良いことだらけです。

テストコードは増えても良いので確認事項をシンプルに

確認事項1,2,3を全て1つのテストメソッドで確認するよりも、3つのメソッドに分けるように意識しましょう。
小さなテストを複数作る方が簡単且つ効果的であり、非常に読みやすいです。
更に後から手も加えやすいので、基本的に必要がない限りはシンプルなテストメソッドを心がけましょう。
しかし、状況に応じて多少複雑なケースはあるかと思いますので、そのあたりは臨機応変に....。

テスト機能に名前をつける

テストコードはメソッドになっていることが多いと思います。
1つの確認事項に対して、1つのメソッドが用意されているようなイメージです。
私が今までいた現場では半分くらいが、TestCase001(){・・・}のようなメソッド名になっていました。
実際に何をしているのかは中を見ないとわかりませんでした。
これでは、読みやすいコードとは言えません・・・。
テストメソッド(テストコード)には確認したいことがわかるように名前をつけましょう。
例えば、事業所コードに紐付く累計売上データの確認テストメソッドならば、どんな名前がいいでしょうか。
"Test_CheckTotalSalesFromOfficeCode"とかが適切じゃないかと思います!(FromはWithとかAttachでもあり?)
このような名前にすることで、テストをしているメソッドであることと、その中で何をしているのかが予測できます。
事前に予測できている状態でコードを見るのと、何も知らないでコードを見るのでは、理解度はかなり変わると思います。
中々面倒かもしれませんが、名前の意識もしていきましょう。


ここまでテストコードについて書きましたが、実際に簡単なことではありません。
事実、テストコードは本来のプログラムありきなものなので、そちらに左右されてしまうことも十分にありえるかと思います。
しかし逆を言えば、テストを意識してコーディングをすることで、よりテストコードが書きやすく読みやすくなるとも考えられます。
私自身もそんな余裕はあまりありませんが、テストを意識しながらコーディングをしていくのも良いのではないでしょうか!!

良いコードを目指して ~リファクタリング~

今日はリファクタリングについて着目して行きたいと思います。

リファクタリングとは、処理結果などが変わらないように注意しつつ中身(コード)を整理することを言います!

まさに、私が目指す”良いコード”に近づく作業です。

主にコードそのものについては他の記事で記述しているので、今回の記事ではリファクタリングの中でもメソッド出しに注目して行きます。

メソッド出しの重要性について

結合度が低くなる

メソッド出しをするということは、引数とreturnを持つ1つのメソッドを作成するということです。

メソッドとして実装することで、引数とreturn以外はほぼ呼び出し元には関連の無いコードになるでしょう。

その結果、呼び出し元コードも、メソッド側のコードもお互いに小依存の関係となり、改修のしやすさにつながります。

再利用性がない処理をメソッド出ししたとしても、結合度を低くすることに繋がることもあります。

例えば、DBの販売履歴テーブルから特定の条件でSELECTし、Dtoクラスに加工する処理があったとします。

単純に1つのロジック内で処理をしていると、どこからどこまでがDtoクラス加工に関与しているのかもコードを読まないといけなく、また改修をする場合は更に他に影響があるかを見なければなりません。

引数を販売履歴のrow(またはList)、returnをDtoクラス(またはList)のconvertSaleshistoryToDtoメソッドとしてメソッド出ししている場合は、加工する処理を改修するとしてもメソッド内に着目すればよいため改修がかなりしやすくなると思います。

細かい部分をメソッド出しすると、結合度を下げることに繋がらないかもしれません。

なるべく大きな処理の纏まりとしてメソッド出しができそうな場所を見つけたら、進んで実行しましょう。

汎用性

これは、メソッド出しをする際の一番わかりやすい目的だと思います。

複数回出現する、同じまたは酷似した処理をメソッド出しすることは基本的にメリットしかありません。

何回も書かなくて済みますし、修正するときも1箇所だけなので良いコードにより近づきます。

私の感覚ですが、汎用性を持たせるのであればなるべくシンプルなメソッドにしましょう。
(極端な例だと、"Nullを空文字,それ以外はそのまま"で返すようなメソッド)

いきなり、先ほど書いたことと矛盾していていますね笑

必ず両方とも守らなければいけないことはなく、むしろ両方の要素を持ったメソッドは少ないでしょう。

メソッド出しをするときは、どういう目的で抽出をするのかを意識して行いましょう!

読みやすさ

コードはシンプルな方が読みやすいです。

メソッド出しをすると、コードをスクロールして読む量が減ります。

実際には別メソッドに記述しているだけですが、そのまま列挙された200行のコードと100行のコード*2では、後者のほうが読みやすい場合の方が多いでしょう。

あっちこっちに飛び過ぎると、可読性が低下しますが、適度なメソッド出しは可読性をもあげるのです!!

どこまでやるか

リファクタリング作業は、定義されていない正解に向かっていくような作業なので、人によって終わらせるタイミングは異なると思います。

また、時間をかければ良いコードに近づけるというものでもありません。
私自身今でも、この作業が果たして正解なのか悩みます。。。

慣れない頃は無理に全体を見ず、ロジッククラスやDaoクラスに1度目を通して見るくらいが良いのではないかと思います。

また、最大でも2回くらいがリファクタリング作業の効率が良い期間かなと感じます。
3回目以降は、よくわからなくなってしまったり、箇所が少なかったりと作業効率が悪くなる気がします。(経験談)

まずは1回、目を通すくらいの感覚がちょうどいいと思うので、やってなかった方は是非やってみましょう!!



リファクタリング作業は自分でやってもなかなかは捗らないかもしれません。

そういう時は他の人にソースをレビューしてもらうと、気付けなかった点に気付けるかもしれません。

良いコードを目指して ~変数の使い方~

少しずつ寒さが和らいで、時の流れを感じますね_(:3 」∠)_

今回は、変数の使い方について注目していきたいと思います!

変数も使い方次第で”良いコード”、つまり他人から見て読みやすいコードの大きな要素になると言われています。

私自身、この内容については普段できていない部分も多かったので、戒めも込めてアウトプットしていきます。笑

わかりにくい処理や、使い回す処理は変数に収める

コードを読み書きしていく中で、必ず複雑な処理は登場します。

そういった処理を変数に収めることで、コードの可読性はかなり上がります!

実例を書いていきます。

if(inputStr.trim().split('-')[0] == '012' ){
    //処理
}

上記の例では、入力した文字列をtrimして、ハイフン分割して・・・と条件判断する前に色々と考えなければいけません。

更に複雑な処理の場合はなお読みにくいでしょう。

こういった場合に、変数にその処理を入れてあげるのです!(説明変数とかいうらしいです)

String userPreviousNumber = inputStr.trim().split('-')[0];
if(userPreviousNumber == '012'){
    //処理
}

どうでしょうか、比較してみると後者のほうが読みやすく感じるのではないでしょうか!

更に後者の場合は同じ処理が必要になった場合に使い回しができます。

また使い回した場合、修正部分が1箇所のみになるのでコードの保守性も上がるでしょう。

処理が複雑に感じたり、使い回す場合については変数に入れて読みやすくすることが良いでしょう!

不要な変数は使用しない

先ほど、複雑な処理は変数に収めたりすると良いと書きましたが、度を超えてしまうとコードは読みにくくなります。

例えばAからB、BからCへ値を入れている処理では、変数Bは全くもって必要ありません。

そもそも最初に上記のようなコードを書くことはまず無いと思いますが、コードを書いて、修正していく中で発生してしまうことも有りえるでしょう。

変数に限った話ではありませんが、コードを一通り書き終えたら無駄な変数が存在しないか確認すると良いでしょう!

スコープを意識する

変数のスコープは必ず意識するようにしましょう。

変数宣言時にこの変数はどこで使うのか、どこまで見えているべきなのか、ということを考えることはとても大切です。

スコープが意識されていない(必要のない箇所からも読み書き可能である)と、主に使っている箇所以外でももしかしたら値を参照/編集している可能性があると意識しながら読まなければいけません。

また、逆に名前のバッティングなどに気づかずコードを書いてしまい、予期せぬ不具合を生んでしまう可能性もあります。

スコープを必要最低限にすることで、読み手側への負担も減ります。

ローカル変数などは、まずは小さい範囲で宣言し、必要な場合に応じてスコープを広げていくのが適切でしょう。


変数は、設計書などにも明確に記載されている場合は少ないと思います。

そのため、良くも悪くもコードを書くエンジニアによってある程度自由に使用できるでしょう。

コードが動くことだけでなく、後の事を考えて良いコードを書くために、変数というものに今一度着目してみてください!!

これからは少しpythonの記事書いていこうかなと思います。

良いコードを目指して ~分岐・繰り返し~

分岐や繰り返し処理にもコードを見やすくする方法は多くあります。

基本的な概念が多いかもしれませんが、改めて再認識することで”良いコード”を目指していきましょう。

分岐する上での注意点

コードを書いていれば、Dtoクラスなどでない限りほとんどのファイルに分岐処理は存在するでしょう。

分岐処理で良いコードを意識すれば、全体的な読みやすさは変わるはずです!

条件はなるべく肯定的に

分岐処理は、必ず条件を伴います。

特に指定がなければ、条件部の条件はコーディングする人が考えると思います。

その際に、肯定系/否定形どちらでも実装可能な場合、特別な意図がない限りは肯定的な意味合いにしたほうが読み手側にとって楽になります。

実例を書いていきましょう。

エラーチェックの結果、エラーとなる場合にはreturnする処理を考えます。

否定的な意味合いの場合、以下のようなコードになります。

    ・・・
    if(!clearFlg){
        return false;
    }
    ・・・

上記の例はシンプルなのでそこまで読みにくさはありませんが、「クリアフラグがTrueじゃない」=問題がある というように否定のニュアンスを考えてしまいます。

また、否定形の場合だと読み間違えてしまう(!を見落としてしまう)可能性もあるでしょう。

そうではなく、例えば上記の場合だと「errorFlg」を条件部にするとそのまま読んでいけるし、読み間違える可能性は低くなります。

全ての条件分岐を肯定的にすることが正しい訳ではありませんが、どちらでも実装可能な場合には特別な意図がなければ肯定的な条件にしましょう。

比較変数の配置

これは恐らく無意識でやられている方も多くいるかと思います。

条件分岐をする際に、変数を変数or定数と比較する場合は必ず左側に比較したい対象を置きましょう。

    ・・・
    if(1000 < salesSum){
        // 処理
    }
    ・・・

上のコードを見たら、なんかむず痒いと感じる人は多いのではないでしょうか。

実際にこれが見やすさと直結するかどうか調べてみましたが、どうも英語の用法と同じだそうです。(比較級とかのやつ)

比較する変数は必ず左側に配置しましょう!

三項演算子の多用は避ける

皆さんはコードを書くときに三項演算子を使うことはありますか?

三項演算子を使うことでよりコードが見やすくなることがあります。

例えば、未成年かどうかを判断して文字列で情報を保持する場合、以下の2パターンが考えられます。

// パターン1 通常分岐
if(age < 20){
    userDto.category = "minority";
}else{
    userDto.category = "adult";
}

// パターン2 三項演算子
userDto.category = (age < 20) ? "minority" : "adult";

見てわかる通り、パターン2のほうがコードとしてすっきりしています。

このように、三項演算子を使えば分岐処理を綺麗に整えることができます。

しかし、三項演算子はシンプルな分岐処理の場合は可読性が上がりますが、少しでも複雑な処理をしてしまうと読みづらくなってしまいます。

私は以前こんなコードに出会いました。

・・・
***Dto.status = (inputSum > 20) ? ( (inputSum > 40) ? 2 : 1 ) : 0;
・・・

少なくとも、1度目を通しただけで理解した人は少ないと思います。

上記は入れ子になっているので当然読みづらさがありますが、真偽それぞれの場合の評価式が複雑になると読みづらくなるため、よく考えていない多用は避けましょう。

繰り返し処理をする上での注意点

繰り返し処理は私が一番勘違いしていた部分です。

以前の私は"良いコード"とは、効率の良いコードというシンプルな考えでした。

1つのfor文の中で、できることは全てぶちこむという事を良い考えとしてコードを書いており、結果プログラムの可読性は下がっていたと思います。

そうならないように、注意点を書いていきたいと思います!

なるべく処理はシンプルに

先にも書いたように、for文の中であれもこれも、と処理を乱雑に書いてしまうとコードの可読性はさがります。

for文などは、シンプルになるように繰り返し処理の目的が達成したら閉じましょう。

また必要になったら極端な話、再度for文を書いてしまえば良いのです。

私も最初は、これのほうが良いのか?と疑問を抱いたのですが、実際利点を書き出してみると、確かにそうだと感じました。

  • for文の中で余計な他の処理をしていないので保守しやすい
  • コードが読みやすい(データの状況が理解しやすい)
  • 数百行以下のループなら処理速度は微々たるものしか変わらない

ループ処理を行う件数が多い場合は影響が大きいかもしれませんが、想定される件数が多くない場合にはfor文をフェーズ毎に分けても良いかと思います。

但しこのあたりは感覚的な部分も多く、まとめたほうが見やすい方もいらっしゃると思うので、自分が見やすいと思う方で書きましょう。(笑)

ネストは浅く

これはif文・for文に共通することですが、ネストは浅くしましょう。

ネストが深くなれば、どの段落で分岐・繰り返し処理が終わるのかがわかりにくくなります。

ではどのようにネストを浅くしていくかですが、不要な分岐や繰り返しをなくす事を考えましょう。

実例を書いていきます。

for(EventDto dto : eventDtoList){
    //Eventステータスが公開の時に処理**を実施
    if(dto.status == 'public'){
        // 処理A
        ・・・
    }
}

上記の例だとif文自体を消すことはできませんが、ネストが深い部分を短くすることができます。

for(EventDto dto : eventDtoList){
    //Eventステータスが公開でない場合は処理**を実施しない
    if(dto.status != 'public'){
        return false;
    }

    // 処理A
    ・・・
}

if文の条件を変えて早めにreturn処理をすることで、for文の中の主処理はインデントが1つ減りました。

こういった早めのreturnなどは読みやすく且つ保守もしやすくなるので是非活用してください!

但し、後続処理やその他諸々でできない場合もあると思うので、そこは適宜対応して行きましょう。



この記事の内容は、基本的なことも多いですが全てにあてはまるものではないと思います。

こういう考え方もあるということを知った上で、皆さんの思うようにコーディングしていくことが大切だと思います!!

良いコードを目指して ~先を見据える~

今回は、初回に定義した"良いコード"には近づきませんが、保守性という意味での良いコードに近づいていきたいと思います!

今回のメインテーマは"先を見据える"です。

プログラムの保守性について

コンピュータシステムに関する評価指標[RASIS]の1要素である、保守性について。
保守性とは、一般的に以下であるそうです。(Wikiより引用)

ソフトウェアプログラムの場合、バグなどの不具合要因を修正したり,性能や使い易さといった特性を改善したり、製作当初に想定していなかった機能の追加や変更を少ない手間やコストで実施・改変が行える容易さを表す。

つまり、作成後にどれだけ手が加えやすいか、また加えるコストが少ないかという観点です。

保守性が高いプログラムにすることは、コストに直結するのでより良いコードであると言えるでしょう。

そんな保守性の高いプログラムに近づいて行こうと思います。


先を見据えるとはどういうことか


皆さんはコードを書く際にどんなことを考えていますか?

私は、設計書などを元に頭の中でロジックを考えながら書いたり、不具合などが起きる要素はないか確認しながら書いていることが多かったです。

ですが、先日職場でこんな言葉を耳にしました。

"このコードは先が見えてないからイケてないね"

そこで、"先を見据える"という事を以前よりも強く意識するようになりました。

"先を見据える"と言うことは、後々のことを考えて効率の良いコードを考えることです!

すみません、噛み砕いて書けなかったので実例を読んでいただければと思います、、、。


先を見据えるコーディング(具体例)

画面に生年月日を入力するインターフェースを考えましょう。

顧客から以下の要件が必須であると依頼を受けました。

  • 1.和暦入力にしてほしい
  • 2.入力チェックをし、和暦として存在しない年月日の場合はエラーにしてほしい

実際に画面側を考えるならば、一般的には以下のような感じでしょう。
※以下、平成30年1月現在のものなので新元号は記載してません。



今回はコントローラ側の入力チェック処理に着目します。

まず、必要な入力チェック処理を考えます。
- 1.和暦毎の"年"の妥当性チェック
- 2."月"の妥当性チェック
- 3.月毎の"日"の妥当性チェック(厳密には和暦とも関連)

これらのチェックを通過した値が正常な生年月日として処理されるでしょう。


さて、前置きが長くなりましたが、実際に"先を見据える"ことを意識してコーディングをしていきましょう。

今回は先のチェック項目の[1]について考えていきます。

まず何も考慮しなかった場合、チェック処理を担うメソッドは以下のように記述することができるでしょう。
(正確には全てStringの引数になりますが省略します。)

public Boolean checkBirthDay(String birthJa , Integer year , Integer month , Integer day){
    //和暦毎の"年"値の妥当性チェック
    if( birthJa == "T" ){
        if( year < 1 || year > 15 ){
            return false;
        }
    }else if( birthJa == "S" ){
        if( year < 1 || year > 64 ){
            return false;
        }
    }else if( birthJa == "H" ){
        if( year < 1 || year > 30 ){
            return false;
        }
    }
    //**以下省略**
}

上記コードは動作すると思いますが、明らかに問題点があります。

既に2019年5月から新元号となるため、必ずプログラムの改修が必要になります。

これは保守性の観点でいくと、あまり良いとは言えないでしょう。

今回の改善策としては、和暦データをメタデータなどに外出ししてしまいましょう。

和暦などは、処理するロジックに使用する"数値"というよりは"データ"という表現が正しいと思うので、ハードコードすることは極力避けましょう。

では、実際にメタデータを利用してMapを使った処理を記述してみましょう。

public Boolean checkBirthDay(String birthJa , Integer year , Integer month , Integer day){
    //                  jpCalendarMap #  [key]:和暦アルファベット1文字  [value]:和暦の最後の年
    Map<String,Integer> jpCalendarMap = jpCalendarDao.getJpCalendarMap();

    //和暦毎の"年"値の妥当性チェック
    if( jpCalendarMap.containsKey(birthJa) ){
        if( year < 1 || year > jpCalendarMap.get(birthJa) ){
            return false;
        }
    }
    //**以下省略**
}

行数として凄くシンプルになりました。

そして何より、後者のプログラムではメタデータ側にデータを追加するだけでチェック処理は正常に動くんです!!

こういった形で、コードを書く際に"この先に起こりうること"を意識することで保守性の高いプログラムを目指すことができます。

プログラム例の余談

西暦年をメタデータ側に持ち、DateFormat型のparse処理で入力チェックを行うのも良いでしょう



"先を見据える"ことは正直、経験と知識が大きく関連してくるでしょう。

事実私もまだまだイケてるコードを書けてる時は少ないと思います。

しかし、少しでも念頭に置いておくことで多少なりとも磨きがかかってくると思うので、より良いコードを目指していきましょう!!

良いコードを目指して ~見た目にこだわる~

コードを書く際に、見た目は気になりますか?

なんとなく嫌悪感を示す方もいるかもしれませんが、見た目にこだわることも”良いコード”に近づく道だと感じています。

”良いコード”については、前回の記事をご覧ください。

今回は、そんなにマメでない私でも取り組みやすかった実例をご紹介していきたいと思います!

縦の意識

何かスポーツの戦術みたいですね。(笑)

これは基本中の基本だと思いますが、インデントを揃えるという事です。

無意識のうちにやってる方も多いのではないでしょうか。

プログラムのインデントを揃える事はもちろんですが、コメントなども縦列を意識するだけで読みやすさがかなり変わります。

プロジェクトとして、画面幅をとらない為に同一行に説明コメントを挿入する決まりがあるとします。
下のコード例を見てみましょう。

String    lastName;  //姓
String    firstName;  //名
String    gender;  //性別
Integer    age;  //年齢
List<**Dto> followList; //フォローリスト
Boolean    isActiveUser;  //有効ユーザ

定義だけのはずが、かなり見にくいですね、、、

次に揃えたコード例を見てみましょう。

String      lastName;      //姓
String      firstName;     //名
String      gender;        //性別
Integer     age;           //年齢
List<**Dto> followList;    //フォローリスト
Boolean     isActiveUser;  //有効ユーザ

かなり見やすくなりました。

極端な例ではありますが、このように縦の意識を持つだけでかなり綺麗になります。

上の例はコメントでしたが、この意識は演算処理やメソッド呼び出しのパラメータなどでも同じ事が言えると思います。

例えば同じメソッド呼び出しが並んだ際に、タイプミスやパラメータ不備など容易に気付くことができます。

何でもかんでも揃えるというよりは、これは揃えたほうが見やすそうだな、、と感じる場合には揃えるようにしましょう。

纏まりの意識

また戦術みたいな言葉になってしまいました。

処理やメソッド毎に纏まりを意識すると見やすくなります。

これも無意識のうちにやってる方も多いのではないでしょうか。

例えば、コンストラクタなどで様々な処理を行うクラスがあるとします。

そのコンストラクタで行う処理を1行ずつ空白行無しで列挙していくとどの部分で何をしているのかが視覚的に分かりづらいです。

”纏まり”を分けるのにも個人差はあるかもしれませんが、処理の趣旨が変わったと感じたら空白行を入れ、纏まりで分けてあげると良いでしょう。

そうすることで、後から見てもパッと見で大体の処理の流れがイメージできますし、改修するにしてもどこに着目すれば良いかが見つけやすくなります。


また、これはメソッド毎に対しても同じ事が言えます。

特定のテーブルに対して操作を行うDaoがあるとしましょう。

Daoの既存メソッドを利用してテーブルにどんな操作が可能なのかは、実際に見てみないとわかりません。
(ドキュメント化してある場合は例外です)

ある改修依頼を受けて、少し異形な返り値のSELECTが必要となった場合に、Daoのメソッドが纏まりもなく列挙してあると、もれなくロードローラーしなくてはなりません。

これでは時間がかかってしまいます。

しかし、Daoの中でもSELECTするメソッドを1区画に纏めていると、確認場所は格段に減ります。
しかも新規メソッド追加となった場合には、その区画の最後に追記してあげるだけで、何ともすっきりします。

処理にしてもメソッドにしても、あるいはクラスにしても"纏まり"を意識しましょう。

適切なコメント

プログラムを書く上でかかせないものが、コメントです。

コメントの有無では読みやすさにかなりの差があると思います。

しかし、ソースコードの50%がコメントだとすると、本当に読みやすいのでしょうか。


コメントは適度且つ情報を与えるものでないと意味がありません。


まず量に関して私が感じることですが、先の"纏まり"毎には最低限あるべきだと思います。

これからどういう類の処理を行うのかがコメントであるだけで、初めて見る側としてはだいぶ楽になります。

その中でも+αで、”ここは説明があったほうがわかりやすいな”とか”改善点があるな”とか補足や注意すべき点を書いていくと良いでしょう。

またコメントは画面幅を必然的にとるものなので、情報量が大事です。

私は、プログラミング覚えたての頃はこんなコメントを書いていました。

//分岐処理
if( *** < 20 ){
     ・・・;
}

恐らく多くの方が思ったでしょう。

"な ん だ こ の コ メ ン ト は"

今の私もそう思います。(笑)

上のコメントの情報量は、はっきり言って全く価値のないものでしょう。
分岐処理なんて、コードを見る立場の人がみればすぐに分かります。

コメントをするのであれば、そのコードからは読み取る事のできない部分や、読み取るのに時間がかかる部分を書いてあげると良いでしょう。

先の例でコメントをするのであれば、以下が適切かと思います。
- どういうケースにこの中の処理を通るのか(分岐条件の日本語化)
- 分岐内で何をしているのかの概要
などが挙げられると思います。


ここまでコメントについて書いてきましたが、適切なコメントを残すことは難しいと思います。
私自身もふと"書くべきことはこれでいいのだろうか"と悩む事もあります。

極力、書いたほうがいいのかなと思ったなら書きましょう。

当たり前ですが、書いてないことは知らない人からしたらわかりません。

例え読みづらくなったとしても、コメント(記録)として残しておけば、仙人が何とかしてくれるでしょう。


次回は、もう少しロジック的な記事を書きたいなと思っています!

このブログももう少し見た目にこだわらなければ・・・

良いコードを目指して ~名前付け~

最近になって自分の書くプログラムが ”良いコード" なのかが凄く気になるようになりました。

例えば、

  • 処理効率は良いのか
  • 他の人が見ても理解しやすいか

など、恐らく良いプログラムの条件はたくさんあるでしょうし、数値化できないものもあると思います。

そこで、私自身が思う ”良いコード” を定義しそれに近づいていきたいと考えています!

良いコードとは


良いコードの条件って何でしょうか。 


私は、半年くらい前まで ”処理効率” をとにかく良くする事が何よりも”良いコード”の絶対的要素であると思い込んでいました。

間違ってはいないのですが、それだけでは”良いコード”とは呼べないと今は思っています。


では何が重要なのか。

今の私が重要視するのは ”他の人が見ても理解しやすいか” という点です。
私が ”他の人が見ても理解しやすいか” を重要視し始めた要因です。

  • 新しく新規参画したメンバーでも読みやすい
  • テストフェーズなどでも、原因を探りやすい
  • 追加改修などの際に、影響範囲があるかがわかりやすい

どれも曖昧な表現ではありますが、”他の人が見ても理解しやすいか” によるメリットは多くあると思います。
 

そのため、”処理効率”よりも“他の人が見ても理解しやすいか”に重点を置いたコードを”良いコード”として考えていきます。
 

プログラミングにおける名前の重要性

 

みなさんは名前付けをする際にどういう事を意識していますか。


”良いコード”に近づくための方法は数え切れないほどあると思いますが、一番身近であり、且つ重要であると思うのが”名前付け”です。


極端な例ですが、以下の2つの変数名が並んだ場合に、どう感じるでしょうか。

Integer sum;
Integer monthlySalesSum;

sumでは何の合計かわからない為、何かを集計していれば違和感を感じません。

しかし、monthlySalesSumは名前から月の売上合計額用の変数だと想定できます。

例えばmonthlySalesSumに月の経費合計額を退避していた場合に”この処理はこれで合っているのだろうか”と疑問を抱くと思います。

こうすることで、名前付けによってプログラムのあるべき姿を想像することが出来るのです。
 

変数宣言時にコメントで補足説明は書けても、変数の利用場所で説明されているわけではありません。

そのため、想像しやすい名前付けをすることがプログラム自体のあるべき姿を思い描かせてくれると最近は感じています。

 
いつか読んだ本に書いてありましたが、”名前付けはコメントのようなもの”という言葉が凄く的確だと感じました。

変数名やメソッド名が的確な状態であれば、極論コメントがなくても読みやすいコードになると思います。

それほど、名前付けは重要です!


※名前やコメントを100%信じる事は危険ですので避けましょう。(特に新しくみるコードでは)
経験がある方もいるかと思いますが、コメントや変数・メソッド名と処理している事が異なっていても実際には正しいこともあったりします。


名前付けする際の注意点

 

実際に重要だと思ってもどういう名前をつけるべきなのか、と考えると思います。

私自身が本や記事、実務を通して思った事を列挙していきます!
 

1)汎用性のある抽象的な単語は避ける

スコープの範囲にもよりますが、汎用性のある抽象的な単語は分かり辛さの根本になると思うので避けたほうが良いと思います。

先の説明例でも利用したsumのような、どのようにも受け止める事のできる変数名をつけてしまうと、コードが読みづらくなります。

そのため、汎用性のある抽象的な単語単体を名前付けに利用することは避けたほうが良いでしょう。

2)長すぎる名前は避ける

長すぎる名前を利用すると、単純に読みづらいです。
また、似たような名前が並んだ場合に同じものとして間違えてしまう可能性もあるため、長すぎる名前は避けましょう。

短くするコツとしては、以下があると思います。

  • 不要な単語を除去する
  • 単語の先頭3~4文字を残す
  • 単語の先頭以外の母音を消す
  • 一般的な略語を利用する

但し、短くしすぎて必要な単語が分かりづらくなるとコードが読みづらくなり本末転等となるので気を付けましょう。

3)一貫性を持つ

当たり前のことのようですが、名前付けに一貫性を持ちましょう。
配属プロジェクトに命名ルールなどがあれば、それにあたると思います。

例えば、同じソースコードの中でも同一単語の略し方が様々であったり、単語の順序が明らかに違ったりするとかなり困惑します。

一貫性(ルール)があるだけで、かなり読みやすいコードになります。



名前付けは単純だけど奥が深いと思います。

今回紹介した名前付けの注意点は基本中の基本に当たると思います。

もっと知りたい!という方は是非調べてみてください!

私自身は名前付けのボキャブラリー自体かなり狭く、命名パターンに偏りもあるので、たくさんのプログラムを読んで命名の幅を広げていきたいです!

もっと読みやすい記事を目指していきます。_(:3 」∠ )_