もっと良いコードを書きたいっと思い、そのような書籍がないか探したら、
「良いコードを書く技術」という、自分にピッタリそうな書籍が見つかったので読んでみました。
良いコードの定義
状況によって異なるとのことですが、本書では、以下が良いコードと定義していました
- ①保守性が高い
- ②すばやく効率的に動作する
- ③正確に動作する
- ④無駄な部分がない
それをこれから、かいつまんで紹介致します。
① 保守性が高い
1.命名
変数名は短くしない
悪い名前の例:「消費税金額をを3桁ごとのカンマ区切りの文字列に変換して出力する」処理
// 消費税をカンマ区切りに変換
String s = fmt(value);
// 整形済み消費税出力
out.println(s);
変数名・メソッド名を短くすると本当に、訳が分からなくなりますね。。
基本自分は省略せずに書くようにしています。
スコープの長さで変数名の長さを短くする
悪い名前の例: ループカウンターの変数名が慣習的ではなく長過ぎる
for (int empCounter = 0; empCounter < employes.size; empCounter++ ){
Employee emp = employees[empCounter];
}
empCounterの文字が長すぎて、可読性がおちますね。
以下のほうがわかりやすい。
for (int i = 0; i < employes.size; i++ ){
Employee emp = employees[i];
}
ループ内の変数や短いメソッド内の変数では、短くしたほうが可読性が向上しますね
※ 個人的に命名するときに使っているもの
codic
プログラマーのためのネーミング辞書
codic おすすめです。
githubの検索
プログラムのネーミングに迷ったら GitHub でコード検索すると参考になる説
Code Spell Checker
VSCodeの拡張機能です。spellが間違ってたら教えてくれます
2.スコープ (依存性を低く)
スコープ = 見える範囲 = 使える範囲 = 依存する範囲 = 保守性に影響を与える範囲
コードを1ヵ所書き換えたいだけなのに、知らないところでバグを生んでしまったこととかよくありますよね。。
- 変数は使用する直前で宣言する
- メソッドに抽出する
- 一時変数のスコープをループ内に閉じ込める
- 代入されない変数にはfinalをつける
をすることによって、依存性が低くなります。
自分は、変数ごと、メソッドごとで、まとめてしまったりしちゃっているので、スコープでまとめるようにしていきます。
3.コードの分割
なぜコードを分割するのかというと、
- 可読性が向上する
- 保守性が向上する
- 再利用性が向上する
からです。
ただ、分割しすぎて、逆に読みづらくなったってことがよくあります。そのファイル内にまとまってたほうが読みやすかったりします。
ここは本書にも書かれていましたが、完璧な答えはないから、試行錯誤していくしかないとのことです。
なので、コードを分割することによって、メリットはあるのか?っと分けるときに考えることが大事ですね、
4.コードの集約
コードの重複はなぜ悪なのか?
- 変更が発生したときに修正作業が大変になる
- コードの見通しが悪くなる
- 保守性が低くなる
コードをまとめる理想は?
「あるべきところにある」ことです。
- メソッドに抽出してまとめる
- 継承でまとめる
- ユーティリティクラスにまとめる
- サービス層にまとめる
- オブジェクトにまとめる
- 定数にまとめる
ただ、まとめすぎも良くない
本来まとめるべきでないものをまとめしまうと、それをバラすのは大変です。
重複がないうちから重複を予想して、コードを抽出すると、間違ったまとめ方をしてしまいます。
自分はフロント側を実装することが多いですが、まとめるときはデザイナーと相談してからまとめたりしています
② すばやく効率的に動作する
パフォーマンスを意識しないと、
- システムが完成してリリースしてみたら、使い物にならないくらい遅かった
- 長時間の使用によりデータ量が増え、表示速度がどんどん遅くなる
- 小さなファイルなら問題ないが、大きなファイルをアップロードしたら一発でサーバーが落ちた
という状況になってしまうかもしれません。。
そうならないために、パフォーマンスのチューニング(改善)が大切で、以下の順番でやっていくのが大切とのことです
※ 自分はフロントエンジニアなので、自分が参考になった書籍やqiitaの記事を紹介させていただきます
1,まずは測定する
「やみくもにチューニングしてアーキテクチャまで大幅に変えて見たが、あまり効果がなかった」という悲劇が起きないように、まずは測定が大事
・Chrome Devtools による フロントエンドパフォーマンスの計測
2,原因を特定する
少しずつ測定の範囲を狭めていき、パフォーマンスが悪い原因箇所を特定する
3,チューニングする
4,チューニング結果を測定する
チューニング前と比べた改善ぶりを数値として確認する
③ 正確に動作する
ユニットテスト
ユニットテストとは?
↓↓↓↓↓↓↓ あなたの記事の内容
→ 単体テストとも呼ばれ、メソッドやクラスの実装コードに対して書かれるテストのこと
───────
→ 単体テストとも呼ばれ、メソッドやクラスなどの実装コードに対して書かれるテストのこと
↑↑↑↑↑↑↑ 編集リクエストの内容
メリットは?
1,網羅的なテストを自動化できる
入力値や期待値を少しずつ変えながら網羅的なテストを自動実行できます
2,回帰テストによりコードが壊れていないことを保証できる
自動化されたユニットテストは、継続的インテグレーションツールを使うことで定期的に実行できる
3,設計の改善につながる
「テストコードから実行できる」設計になっている必要があり、特に再利用可能なコンポーネントやライブラリの開発において良い設計への改善を促してくれる
④ 無駄な部分がない
抽象化
「似ているものを同じように扱うことでプログラミングを簡単にすること」
以下は例
- 共通的な処理をまとめて親クラスを作成する
- データベースへの接続情報を設定ファイルに外だしする
- 似たような振る舞い(メソッド)をインターフェースとして抽出するなど
最後に一言
何か間違っている点があれば、教えて頂けたら幸いです。
よろしくお願い致します。
また「いいね!」してもらえるとすごい嬉しいです!!