Good Code, Bad Code ~持続可能な開発のためのソフトウェアエンジニア的思考
発売日 : 2023/1/28
目次
> 1.3.5 コードを再利用、汎用化しやすくする
> 1.3.6 テストしやすいコードを書き、適切にテストする
> 1.4 高品質なコードを書くことは、開発のスピードを遅らせるのか
> 3.1 あなたのコードと他のエンジニアのコード
> 3.1.1 あなたにとっては明確なことでも、他の人にとっては明確ではない
> 3.1.2 他のエンジニアは、不注意であなたのコードを壊す
> 3.1.3 あなたはやがて、あなたのコードのことを忘れる
> 3.2 どうやってあなたのコードの使い方を理解するのか
> 4.1.3 エラーから回復可能かどうかは、呼び出し元だけが知っている
> 4.1.4 呼び出し元が回復可能なエラーを呼び出し元に認識させる
> 4.3.7 暗黙的:Promise型かFuture型
> 4.5 呼び出し元が回復したい可能性のあるエラーを通知する
> 4.5.2 明示的なテクニックを利用すべきという意見
> 4.5.3 筆者の意見:明示的なテクニックを使う
> 5.1.1 わかりづらい名前は、コードを読みにくくする
> 5.1.2 コメントは、わかりやすい名前の不適切な代替である
> 5.2.2 コメントは、必ずしも読みやすいコードの代わりにはならない
> 5.2.3 コメントは、コードが存在する理由を説明するのに最適である
> 5.2.4 コメントは、役立つトップレベルの要約を提供できる
> 5.3.1 簡潔ではあるものの理解できないコードは避ける
> 5.3.2 解決策:より多くの行が必要だとしても、コードを読みやすくする
> 5.4 一貫したコーディングスタイルにこだわる
> 5.4.1 一貫性のないコーディングスタイルは混乱を招くリスクがある
> 5.4.2 解決策:スタイルガイドを採用して、それに従う
> 5.5.2 解決策:ネストを最小限に抑えるようにコードを再構築する
> 5.5.3 ネストは多くのことをやりすぎている結果である
> 5.5.4 解決策:コードを小さな関数に分割する
> 5.7.1 説明のない値は混乱を招く可能性がある
> 5.7.2 解決策:適切な名前の定数を使用する
> 5.7.3 解決策:適切な名前の関数を使用する
> 5.8.1 無名関数は小さなものへの使用に最適である
> 5.8.3 解決策:代わりに名前付き関数を使用する
> 5.8.4 巨大な無名関数は問題になる可能性がある
> 5.8.5 解決策:巨大な無名関数を名前付き関数に分割する
> 5.9 すばらしい新しい言語機能を適切に使用する
> 5.9.1 新しい機能でコードを改善できる可能性がある
> 5.9.2 よく知られていない機能は混乱を招く可能性がある
> 6.1.1 マジックバリューはバグにつながる可能性がある
> 6.1.2 解決策:null、オプショナル、エラーを返す
> 6.1.3 マジックバリューは思いがけず発生することがある
> 6.2.1 空のコレクションを返すことでコードが改善することもある
> 6.2.2 空の文字列を返すと、問題が発生することがある
> 6.2.3 より複雑なnullオブジェクトは想定外の事態を起こす可能性がある
> 6.2.4 nullオブジェクトの実装が想定外の事態を起こす可能性がある
> 6.3.2 予期せぬ副作用は問題になる可能性がある
> 6.3.3 解決策:副作用を回避するか明白にする
> 6.4.1 入力パラメーターを変更すると、バグが発生する可能性がある
> 6.5.1 極めて重要な入力値が欠けているときに何もしないと、想定外の事態を起こす可能性がある
> 6.6 将来的にも有効に使い続けられるように設計された列挙型処理
> 6.6.1 将来の列挙値を暗黙的に処理すると、問題が発生する可能性がある
> 6.6.2 解決策:全ケースを網羅したswitch文を使用する
> 6.6.4 警告:別のプロジェクトの列挙型に依存する
> 6.7 これらのすべてをテストで解決することはできないか?
> 7.1.3 解決策:不変性を実現するデザインパターンを使用する
> 7.2.1 深い可変性は誤用につながる可能性がある
> 7.2.2 解決策:すべてを防御的にコピーする
> 7.2.3 解決策:不変のデータ構造を使用する
> 7.3.1 あまりにも汎用的な型を使うと、コードを誤用する可能性がある
> 7.4.1 整数で時刻を表すと、問題が発生する可能性がある
> 7.4.2 解決策:時間に適切なデータ構造を使用する
> 7.5 データに対して信頼できる唯一の情報源を持つ
> 7.5.1 2つ目の信頼できる情報源の存在が、不正な状態につながる可能性がある
> 7.5.2 解決策:一次データを信頼できる唯一の情報源として使用する
> 7.6 ロジックに対する信頼できる唯一の情報源を持つ
> 7.6.1 ロジックに対する信頼できる情報源が複数あるとバグが発生する可能性がある
> 7.6.2 解決策:信頼できる唯一の情報源を持つ
> 8.1.1 ハードコーディングされた依存関係は問題になる可能性がある
> 8.1.3 DIを念頭に置いてコードを設計する
> 8.2.1 具体的な実装に依存することは変更への対応力を制限する
> 8.2.2 解決策:できる限りインターフェイスに依存する
> 8.3.1 クラスの継承は問題になる可能性がある
> 8.3.2 解決策: コンポジションを使用する
> 8.4.1 他のクラスに関心を持ちすぎると、問題が起きる可能性がある
> 8.4.2 解決策:クラスが自分自身に関心を持つようにする
> 8.5.1 カプセル化していないデータは扱いにくい
> 8.5.2 解決策:関連データをオブジェクトまたはクラスにグループ化する
> 8.6 戻り値の型から実装の詳細が漏洩することに注意する
> 8.6.1 戻り値の型から実装の詳細が漏洩すると、問題になる可能性がある
> 8.6.2 解決策:抽象化レイヤーに適した型を返す
> 8.7 例外の中から実装の詳細が漏洩することに注意する
> 8.7.1 例外から実装の詳細が漏洩すると、問題が発生する可能性がある
> 8.7.2 解決策: 例外を抽象化レイヤーに適したものにする
> Chapter 9 コードを再利用、汎用化しやすくする
> 9.1.1 コードを再利用すると、想定がバグにつながる可能性がある
> 9.1.3 解決策:想定が必要な場合は強制する
> 9.2.1 グローバル状態がコードを安全に再利用できなくする可能性がある
> 9.3.1 下位レイヤーでデフォルトの戻り値を使うと、再利用しづらくなる可能性がある
> 9.3.2 解決策:より上位レイヤーでデフォルト値を提供する
> 9.4.1 不必要なものを受け取る関数は再利用しづらい
> 9.4.2 解決策:関数が必要なものだけを受け取るようにする
> 9.5.1 特定の型に依存すると、汎用性が低くなる
> 10.3 パブリックAPIに注目しても重要な動作は無視しない
> 10.3.1 重要な動作がパブリックAPIの外部にある可能性もある
> 10.4.4 モックとスタブが問題になる可能性がある
> 11.1 ただ関数をテストするのではなく動作をテストする
> 11.1.1 1関数につき1テストケースでは不十分である
> 11.1.2 解決策: 個々の動作をテストすることに焦点を合わせる
> 11.2 テストのためだけに公開するのは避ける
> 11.2.1 プライベート関数をテストするのは悪いアイデアである
> 11.2.2 解決策:パブリックAPI経由のテストを選ぶ
> 11.2.3 解決策:コードを小さい単位に分ける
> 11.3.1 一度に複数の動作をテストすると、テストが不十分になる
> 11.3.2 解決策:それぞれのシナリオごとにテストケースを作る
> 11.4 共通のテストのセットアップを適切に使う
> 11.4.1 状態の共有は問題になる可能性がある
> 11.4.2 解決策:状態の共有を避けるかリセットする
> 11.4.3 構成の共有は問題になる可能性がある
> 11.4.4 解決策:テストケースごとに重要な構成を定義する
> 11.5.1 不適切なマッチャーは失敗の不十分な説明につながる
> 11.5.2 解決策:適切なアサーションマッチャーを使う
> 11.6 DIを使ってテスタビリティを補強する
> 11.6.1 ハードコーディングされた依存関係はテストを不可能にする
> Appendix A チョコレートブラウニーのレシピ
> Appendix B null安全とオプショナル