😺

良いコード/悪いコードで学ぶ設計入門 を読んでみました

2024/02/16に公開

はじめに

現在、私が所属するチームでは、本番運用をしているシステムを扱っています。
ただ、何年も前に構築されたシステムなので、レガシーな設計や実装となっていました。
日々の運用の中でコードを修正を行うことが多々あるのですが、より良く改善するのをどうすればいいかを学ぶために、チームで『良いコード/悪いコードで学ぶ設計入門』の輪読会を行いました。

本書では、開発力を低下させ、ソフトウェアの成長を阻害する、設計や実装上の問題を「悪魔」とたとえ、開発に潜む悪魔を知覚し、退治できるようになるための設計技術書です。
今回、本の内容の整理や復習を兼ね、章毎の簡単な紹介と解説、感想をまとめました。

https://www.amazon.co.jp/良いコード-悪いコードで学ぶ設計入門-―保守しやすい-成長し続けるコードの書き方-仙塲/dp/4297127830

第1章 悪しき構造の弊害を知覚する

この章では、悪しき構造が引き起こす代表例を紹介しています。
コードの読みにくさや保守性の低さなど、様々な側面から悪影響を見極めることが重要です。

  • 意味不明な命名
  • 技術駆動命名や連番命名
  • 条件分岐のネスト
  • データを保持するだけのクラス
  • 低凝集によって引き起こされる弊害
    • 重複コード
    • 修正漏れ
    • 可読性低下
    • 未初期化状態(生焼けオブジェクト)

第2章 設計の初歩

この章では、設計の基本的な考え方や原則についての解説でした。
基礎的な事ですが、高凝集で堅牢なクラスを設計するために大事なことを述べていました。

私が担当しているプロダクトは、無意味に名前を省略してしまうことや、意味のあるまとまりでメソッド化されていなかったので、基本的なことですが注意していきたいです

  • 省略せずに意図が伝わる名前を設計する
  • 変数を使い回さない、目的毎の変数を用意する
  • ベタ書せず、意味のあるまとまりでメソッド化
  • 関係し合うデータとロジックをクラスにまとめる

第3章 クラス設計 -全てにつながる設計の基盤-

この章では悪魔退治の基本となるクラスの設計方法を学びました。
クラスを適切に設計することが、複雑で難解な条件分岐やメソッドの構造改善につながります。

ちょうど本章を読み終えた後に、正しく設計できていなかったクラスの static なインスタンス変数が原因で不具合があり、クラス設計の大事さを感じております😭

  • クラス単体で正常に動作するよう設計する
  • 成熟したクラスへ成長させる設計術
  • 悪魔退治の効果を検証する
  • プログラム構造の問題解決に役立つ設計パターン

第4章 不変の活用 -安定動作を構築する-

クラスを適切に設計することが、複雑で難解な条件分岐やメソッドの構造改善につながります。
不変性は、ソフトウェアの安定性や信頼性を高めるために重要な概念です。
この章では、不変性をどのように活用して安定した動作を実現するかに焦点を当てています。
私が担当しているプロダクトは、不変の活用ができていなかったので、とても参考になりました。

  • 再代入
  • 可変がもたらす意図せぬ影響
  • 不変と可変の取り扱い方針

第5章 低凝集 -バラバラになったモノたち-

低凝集度の高いコードは、理解が難しく、保守性が低下します。
この章では、低凝集度の問題を克服するために、低凝集の構造と対策についての解説でした。
こちらも私が担当するプロダクトでは低凝集な作りとなっていたので、構造や対策など非常に分かりやすかったです

  • static メソッドの誤用
  • 初期化ロジックの分散
  • 共通処理クラス(Common・Util)
  • 結果を返すために引数を使わないこと
  • 多すぎる引数
  • メソッドチェイン

第6章 条件分岐 -迷宮化した分岐処理を解きほぐす技法-

複雑な条件分岐は、コードの理解や保守性を著しく低下させる原因となります。
この章では、条件分岐をどのようにシンプルにして理解しやすくするための解説でした。

パターンマッチングやポリモーフィズムなどのテクニックを使用して、分岐処理を簡潔にし、コードの複雑さを軽減する方法を学びました。
複雑な条件分岐を廃止し、interfaceを使いこなせる中級者を目指したいです。

  • 条件分岐のネストによる可読性低下
  • switch 文の重複
  • 条件分岐の重複とネスト
  • 型チェックで分岐しないこと
  • interface の使いこなしが中級者への第一歩
  • フラグ引数

第7章 コレクション -ネストを解消する構造化技法-

コレクションは、多くの場面でデータを効率的に管理するために利用されますが、適切に扱わないとネストが深くなり、コードの理解が難しくなります。
この章では、効果的なコレクションの扱い方や、ネストを解消する構造化技法についての解説でした。
低凝集に陥りやすいコレクション処理を解決する、ファーストクラスコレクションの設計パターンは、ぜひ取り入れたい内容でした。

  • わざわざ自前でコレクション処理を実装してしまう
  • ループ処理中の条件分岐ネスト
  • 低凝集なコレクション処理

第8章 密結合 -絡まって解きほぐせない構造-

密結合は、コードの可読性や保守性を低下させる主な原因の一つです。
この章では、密結合の問題がどのように発生し、どのように解消するかの解説でした。

今の自分達が扱っている既存のコードでやるのは、非常に時間がかかりそうな内容だと感じました。😢
まずは新しく追加するときに肝に銘じようと思います。

  • 密結合と責務
  • 密結合の各種事例と対処方法

第9章 設計の健全性をそこなうさまざまな悪魔たち

設計においては、さまざまな要因が健全性を脅かします。
この章では、設計に潜む悪影響をもたらす悪魔たちについての解説でした。

下記の中でも、null 問題は現在のチームで度々起こっています(NullPointerExceptionが辛い😭)

  • デッドコード
  • YAGNI 原則
  • マジックナンバー
  • 文字列型執着
  • グローバル変数
  • null 問題
  • 例外の握りつぶし
  • 設計秩序を破壊するメタプログラミング
  • 技術駆動パッケージング
  • サンプルコードのコピペ
  • 銀の弾丸

第10章 名前設計 -あるべき構造を見破る名前-

名前はコードの可読性と理解を劇的に向上させる重要な要素です。
この章では、良い名前の特性や原則についての解説でした。

名前設計は疎かにしてしまいがちですが、非常に重要なスキルです。
名前をどうするか、ということに議論に時間を使うことが多々ありますが、
その都度適切な名前を設計していきたいと考えさせられました

  • 悪魔を呼び寄せる名前
  • 名前を設計する - 目的駆動名前設計
  • 設計時の注意すべきリスク
  • 意図がわからない名前
  • 構造を大きく歪ませてしまう名前
  • 名前的に居場所が不自然なメソッド
  • 名前の省略

第11章 コメント -保守と変更の正確性を高める書き方-

コメントはコードの理解を助けるために重要ですが、適切に使われていない場合は逆効果になることもあります。
この章では、どのようなコメントが読み手を混乱させてしまうのかを示します。
そのうえで、理解を促し、保守や変更の正確性を高めるコメントのしかたの解説でした。

退化したコメントや命名コメント規則をごまかすためのコメントは、自分の担当している箇所でも結構あります。
今のプロダクトを良く知る人間ならそれほど問題にならないのですが、新規メンバーが加入してきた時は混乱を招くだけなので、改善していきたいと思いました。

  • 退化コメント
  • コメントで命名規則をごまかす
  • 意図や仕様変更時の注意点を読み手に伝えること
  • コメントのルール まとめ
  • ドキュメントコメント

第12章 メソッド(関数) -良きクラスには良きメソッドあり-

この章では、良いメソッドの特性や原則についての解説でした。
第3章、第4章のクラスの設計と同じく、非常に大事な章だと感じました

  • 必ず自身のクラスのインスタンス変数を使うこと
  • 不変をベースに予期せぬ動作を防ぐ関数にすること
  • 尋ねるな、命じろ
  • コマンド・クエリ編
  • 引数
  • 戻り値

第13章 モデリング -クラス設計の土台-

モデリングは、ソフトウェア設計の土台となる重要なプロセスです。
この章は、適切なモデリング技法やツールの活用方法についての解説でした。
今後新規で追加や実装を行う際に、こちらで学んだ内容を活かしたいです。

  • 邪悪な構造に陥りがちな User クラス
  • モデリングの考え方とあるべき構造
  • 良くないモデルの問題点と解決方法
  • 機能を左右するモデリング

第14章 リファクタリング -既存コードを成長に導く技-

リファクタリングは、既存のコードを再構築して品質を向上させるプロセスです。
この章は、リファクタリングの基本的な原則や手法についての解説でした。
リファクタリングを行う機会は結構あるので、この章での学びを活かしたいです

  • リファクタリングの流れ
  • ユニットテストでリファクタリングのミスを防ぐ
  • あやふやな仕様を理解するための分析方法
  • IDE のリファクタリング機能
  • リファクタリングで注意すべきこと

第15章 設計の意義と設計への向き合い方

この章は、設計の意義や重要性についての解説でした。
この章を通じて、設計に対する新たな視点を得ることができました。

  • 本書はなんの設計について書いたものなのか
  • 設計しないと開発生産性が低下する
  • ソフトウェアとエンジニアの成長性
  • 課題を解決する
  • コードの良し悪しを判断する指標
  • コード分析をサポートする各種ツール
  • 設計対象と費用対効果
  • 時間を操る能力者になろう

第16章 設計を妨げる開発プロセスとの戦い

この章では、設計品質をおとしめてしまう開発プロセスの問題を取り上げていました。
問題は、スキル不足以外に心理的要因やコミュニケーション要因、組織的要因などさまざまです。

  • コミュニケーション
  • 設計
  • 実装
  • レビュー
  • チームの設計力を高める

第17章 設計技術の理解の深め方

さらに奥深く設計を学んでいくための書籍や学習方法を紹介でした。

  • さらにステップアップするための設計技術紹介
  • 設計スキルを高める学び方

まとめ

非常にためになる内容でした🙌
特にレガシーなコードで運用・保守を行っている方で、どのように改善するか悩んでいる方は、ぜひ読んでみるのを検討してはいかがでしょうか。
また、本書のサンプルコードは Java で書かれているので、Java を使用している方はもちろんのこと、オブジェクト指向であれば、言語を問わず広く有効な設計手法となるよう考慮して書かれています。
先月から輪読会をはじめましたが、設計、コーディング、レビューなどの様々な場面で、本書で学んだことが活かせているように感じています😀

レスキューナウテックブログ

Discussion