プログラミング 読書

「良いコード/悪いコードで学ぶ設計入門」を読んだ

2022年7月4日

面白かった。

クラス設計、不変の活用、低凝集、条件分岐、コレクション、密結合、名前設計、コメント、メソッド、モデリング、リファクタリングなどの視点で悪いコードを例に良いコードの書き方を教えてくれる。

読んで終わりじゃなくて実際に仕事に活かすためにチェックリストやツールでカバーしたいところ。

rubocop、rails_best_practices、rubycritic、SimpleCovは導入してたりしてなかったりするけど高凝集疎結合ってどうやって進めていこうと調べてたらpackwerkを見つけたので試してみたい。

GitHub - Shopify/packwerk: Good things come in small packages. https://github.com/Shopify/packwerk

以下は読書メモ

  • 低凝集
    • 凝集度
    • staticメソッドはインスタンス変数を扱えない
    • 共通クラスCommon、Utilに消費税計算処理、退会チェック
    • 多すぎる引数
      • データを引数として扱うのではなくクラスに持たせる
    • メソッドチェインで内部詳細を渡り歩くつくり
      • デメテルの法則に反している
  • 条件分岐
    • 巨大なネスト
      • 早期returnでネストを浅くする
    • switch文をinterfaceやMapに
      • instanceofで型判定するんだったらinterfaceを使う意味がない
    • フラグ引数
      • メソッドの内部ロジックを読まないといけなくなる
      • メソッドを分離する
  • コレクション
    • 自前でコレクション処理を実装してしまう
    • for文の中でif文、anyMatchを使う
    • 「四角い」車輪の再発明
    • 早期continueでネストを浅くする
    • 早期breakでネストを浅くする
    • unmodifiableList 外部には不変にして返す
  • 密結合
    • 単一責任の原則
    • DRY原則の誤用
      • 概念が違えばDRYにすべきではない
    • 継承より移譲
    • 継承より集約
    • 影響スケッチ
    • GitHub - dddjava/jig https://github.com/dddjava/jig
    • なんでもPublicで密結合
    • 基本はpackage private
      • パッケージ外に公開すべきクラスだけpublic
    • privateメソッドだらけ
      • 単一責任ではなく多くの責務を持ってしまっているので分離する
    • 高凝集の誤解からくる密結合
    • スマートUI
      • 表示とそれ以外の責務をそれぞれのクラスに分離する
    • 巨大データクラス
    • トランザクションスクリプトパターン
    • 神クラス
      • レガシーコード改善ガイド
  • 設計の健全性を損なう様々な悪魔たち
    • デッドコード
    • YAGNI
    • マジックナンバー
    • 文字列型執着
      • みたことない
    • グローバル変数
    • NullPointerException
      • 防具未装備をnullから0に
      • null安全
      • Kotlinはデフォルトでnull非許容型、コンパイルエラーになる
    • 例外の握り潰し
    • 設計秩序を破壊するメタプログラミング
    • リフレクション
  • 名前設計
    • 利用規約を読んでみる
      • サービスの取り扱いやルールが極めて厳密な言い回しになってる
      • クラスに反映させる、ビジネスルールとクラスが一致してる
      • 顧客クラスでいいのか?宿泊客と支払者にわける
    • 名前に無頓着だとすべてが瓦解する
      • 会話には登場するのにコードには登場しない名前に注意
    • 形容詞
      • もともとのHP、補正されたHP
    • 連番命名
      • Class001
      • method002
    • 動詞+目的語のメソッド名に注意
      • Enemy.addItemToParty は PartyItems.add
      • Common.isMemberInConfusion は Member.isInConfusion
  • メソッド
    • コマンド・クエリ分離
    • エラーは戻り値で返さない、例外をスローすること
    • 戻り値がLocation(-1, -1)はエラーとするみたいなのはNG
    • ある値に複数の意味を持たせるダブルミーニングは避ける
  • モデリング
    • Userクラスは巨大化しやすい
      • 目的別にモデリングする
      • GitHubのユーザー設定画面
        • Account、Profile、Account securityなど
  • リファクタリング
    • 無駄な仕様を削除することも視野に
    • ソフトウェアの仕様は利益に貢献するよう定められるもの
    • ほとんど利益に貢献しない仕様のコードに対して、わざわざ開発コストを割いて一生懸命リファクタリングしても開発生産性の向上には貢献できません
    • 著者はリファクタリング専門のエンジニア
      • Ruby on RailsをRubyMineで
      • Active Recordから責務のことなるロジックを引き剥がし別のクラスとして分離する
      • 検索時にノイズが混じらないようにユニークな命名にしている
      • 杓子定規にリファクタリングせずフレームワークの特性を考慮
      • 動的型付け言語のリファクタリングは高難度
  • 設計の意義と設計への向き合い方
    • 木こりのジレンマ
    • 実行可能コードの行数
    • 循環的複雑度
    • 結合度
    • チャンクとマジカルナンバー4
    • Code Climate Quality
    • Understand
    • Visual Studio
    • 非エンジニアはシステムの表面的な機能しかみえない
      • 可視化と設計力が必要
  • 設計を妨げる開発プロセスとの戦い
    • コミュニケーションが希薄
    • コンウェイの法則
    • 心理的安全性
    • 早く終わらせたい心理
      • 品質低下の罠
    • 粗悪なコードは綺麗なコードを書くより常に遅い
    • 割れ窓理論とボーイスカウトの規則
      • 敬意と礼儀
      • Chromiumの尊敬に満ちたコードレビュー
      • 正しければ何を言ってもいいというのは幼稚な考え方
    • チームの設計力を高めるために仲間を集める
      • 設計責任者を立てる

-プログラミング, 読書
-