2019年7月30日火曜日

Clean Code アジャイルソフトウェア達人の技

コードにつていての原則などを説明している本。
すごい量が多いので、じっくり一回だけ読むというよりかは何回か読んだほうが良いと思う。
設計の技法などについて読むことが多いと思うけど、その設計を支えるべきcleanなcodeを作成する具体的な技法が習得するのも重要だと思う。
名前、関数、コメント、書式化、オプジェクトとデータ構造、エラー処理、境界、単体テスト、クラス
などがある。システムからは、やや設計的な内容になっていく。

それぞれの要点をまとめてみることにするが、最後のにおいのところだけをチェックリストのように使ってもよいのではないかと思えてくる。

・名前・意味のある名前
マジックナンバーを避けるなどして意味のある名前をつける
発音可能な名前をつける
検索可能な名前をつける
クラス名には名詞や名詞句を使う。InfoやManagerなどは避ける
メソッド名には動詞や動詞句をつけよう

・関数
関数は小さく、一つのことを行おう
関数の引数は、だいたい2つまでにする。3つまでは許すが4つはやめるべき
引数booleanはやめるべき、2つの目的が一つの関数にまとまっていることを示すから
引数が多くなる場合は、引数objectを作るのがよい
副作用は作ってはいけない。例えば、getなのに何かをinitializeしたり
コマンド、参照分離原則、参照しながら変更するをしてはいけない。変更するor参照する
try-catchの中身は関数にしたほうがよい
DRY(Don't Repeat Yourself)の原則、コピーすんなってこと

・コメント
意図や背景を説明するコメント
HTMLコメントはやめる。Javadocの出力は美しいかもしれないがコードとしては読みにくい

・書式化
Coding conventionのこと。基本的にはツールでformatを整えたりチェックしたりする方が懸命である

・オブジェクトとデータ構造
オブジェクトは操作を提供してデータを隠し、データ構造はデータのみを提供する
どちらが優れているということもない。データ構造の種類が増えていく場合は、オブジェクトのほうが良いが、処理の種類が増えていく場合はデータ構造の方が良い
一番ダメなのは、データ構造を公開しているが処理も持っているクラス

・エラー処理
アーリーリターンよりは例外
nullは返さないし、入れない

・境界
3rd partyのライブラリがよくわからなかったら、テストを書いてみるとよい。学習テストという。

・単体テスト
失敗するテストの前に、製品コードを書かない
単体テストは一つづつ書く。コンパイルして失敗したら次
失敗している単体テストが通るまで次に行かない
データ構築、データ操作、期待結果検証の3構造にすべてのテストをする。
1つのテストで1つの概念をテストしよう
テストの5原則FIRST
Fast - 素早い実行
Independent - テスト動詞が独立している
Repeatable - 何度でも再現可能
Self-Validating - 即時に結果がわかる
Timely - 書きたいときにすぐかける

・クラス
SRP(Single Responsibility Principle)単一責務の原則
変更の理由は常にひとつ
凝集性を高めるには、関数内で操作するメンバー変数が多いこと。


以降はわりとデザインの話が多くなる。
Clean Architectureと重なる面も多い。

・システム
決定は、手遅れになるギリギリまで遅延させることが最善。なぜなら、その時が一番情報があるはずだから

・創発
優れた設計などには原則がある。4原則。それを守ることで設計が単純化されて洗練される
全テストを実効する
重複がない
プログラマの意図が表現されている
クラスとメソッドを最小化する
プログラマの意図が表現されているというのがわかりにくかったが、要すると小さくすることで意図が曖昧にならないようにすることだ。

・同時並行性
マルチスレッドプログラミングで本がもう一つ必要だと思うが、原則としては
データスコープを限定する
データのコピーを利用する
スレッド間でデータの共有をしない
シングルスレッドでも動くようにする

具体例については、電子書籍だととても読みにくいものになっている。
ただ、匂いについてはチェックリストにしてもよいかも

C1 不適切な情報
C2 陳腐化したコメント
C3 冗長なコメント
C4 記述不足なコメント
C5 コメントアウトされたコード
E1 ビルド手順が1行でない
E2 テスト手順が1行でない
F1 引数は1〜2まで、せいぜい3つ
F2 out引数はだめ
F3 フラグ引数はだめ
F4 呼び出されていない関数は消す
G1 Java, HTML, Englishなどの複数言語はだめ
G2 当然の振る舞いは実装すべし
G3 境界値について正確な振る舞いを定義して、テストを書こう
G4 常に安全に倒す。ユーザーは悪意があるとみなす。
G5 DRY
G6 抽象レベルを揃える。abstract classで、utilityなど具体的なものを書かない。それは定数なども含む
G7 base classが具象クラスのことを知っていてはならない
G8 情報過多を避ける。スコープを小さくする
G9 デットコードは消す
G10 垂直分離、local変数は使う直前、private functionは使うすぐ下におく
G11 一貫性、あるクラスのインスタンスにつけた名前はどこでも同じものを使う
G12 雑然を避ける、実装のないコンストラクタなど
G13 人為的な結合を避ける。雑に一般的なものを具体的なクラスに含めたりしないこと。それがほかから使われたときに結合を生む。
G14 機能の羨望、クラスを引数として、そのクラス内のデータを操作しているならば、そのクラス内に関数を移動させたほうがよい。
G15 boolean引数など、振る舞いを選択させる引数はだめ
G16 コードの意図が正しく伝わる内容にする
G17 適当に変数を置くのではなく、適切な場所を選んで配置する。
G18 まよったら非staticにする
G19 変数自体を説明的にする
G20 関数名は何をするのハッキリと分かるようにする
G21 関数内部で何が行われているのか自明にする
G22 依存を物理的なものにする。物理的に持つべき場所に変数や定数などを定義する
G23 switchは一つまでにする。それ以上が必要ならばストラテジーを使えば良い
G24 コーディングコンベンションに従おう
G25 マジックナンバーは定数にする
G26 コードに曖昧な点をなくす。
G27 規約での制限よりも構造により制限する
G28 条件を関数化する(isXXXとか)
G29 否定条件を避ける
G30 関数で行うことは一つだけ
G31 呼び出し順が重要なときには、戻り値を次の関数の引数とするように順次処理が進むのを強制する
G32 いいかげんに内部にinnerクラスを作るなど、適当にならない
G33 境界条件はカプセル化する。ひとつに纏める
G34 抽象レベルを揃える。タグとサイズなど
G35 設定可能な値(キャパシティなど)は、できるだけ上位レイヤーに置く
G36 a.getB().getC().doSomethingのような構造は避ける
J1 import package.*を使って冗長なimportを避けよう
J2 interfaceに定数を定義して継承するのはやめる。static importで十分
J3 定数よりenum
N1 実装が予想できる関数名をつける
N2 interfaceでは具体的な名詞は避けたほうが無難
N3 できるだけ業界標準の名前を利用する
N4 関数名は長くなっても、内部で何をやっているか明確にする
N5 長いスコープで利用される変数は長めにする
N6 変数目m_とかのprefixはもう辞める
N7 createOrReturnXXXのように副作用があるならば、関数名で説明する
T1 テストは網羅的に行おう
T2 カバレッジツールを使おう
T3 些細なものでもテストを書こう
T4 @Ignoreはまずいサイン
T5 テストでは境界条件を忘れずに
T6 バグを見つけたらテストを足そう
T7 テストの失敗からバグが明らかになる
T8 テストで実行されていないところにバグがあるかも
T9 テストは高速化を追い求めるべき


Clean Code アジャイルソフトウェア達人の技 Robert C.Martin https://www.amazon.co.jp/dp/4048930591/ref=cm_sw_r_tw_dp_U_x_jJYpDbCM0YV0S

0 件のコメント:

コメントを投稿