幡ヶ谷亭直吉ブログ

娘のここねと格闘するエンジニア。

『改訂新版 良いコード/悪いコードで学ぶ設計入門』を読んで ~ チームでコードを成長させていくために

読書メモ。2025年47冊目。
『良いコード/悪いコードで学ぶ設計入門』を読んでの感想となります。(2025/6/25記載/27更新)

本の概要

本書は、より成長させやすいコードの書き方と設計を学ぶ入門書です。筆者の経験をふまえ構成や解説内容を見直し、より実践的な一冊になりました。

システム開発では、ソフトウェアの変更が難しくなる事態が頻発します。 コードの可読性が低く調査に時間がかかる、 コードの影響範囲が不明で変更すると動かなくなる、 新機能を追加したいがどこに実装すればいいかわからない……。

変更しづらいコードは、成長できないコードです。 ビジネスの進化への追随や、機能の改善が難しくなります。

成長できないコードの問題を、設計で解決します。

引用:

gihyo.jp

動機

  • 1年前に読んだ初版が面白かった記憶が新しい。

  • 改訂新版の案内が魅力的で気になっていました。

    gihyo.jp

  • そんななか『プリンシパル・オブ・プログラミング』でコーディング=設計ということを意識し始めた若手エンジニアの課題図書に選書!!

    hiliteeternal.hatenablog.com

感想

改めて若手エンジニアの頃に出会いたかった一冊。
図書館システムなどでの説明よりゲームという身近な題材で説明されているのが、まだ業務やソフトウェア開発に不慣れなエンジニアにも習得しやすい内容なのではと思っています。
また、こうした書籍を通して、チーム内でのコードに対する認識を揃えて育てていけることはとても重要な機会だと思っています。

中堅エンジニアとの感想戦での学び

若手エンジニアの感想戦に向けて、同時に読んでいた中堅エンジニアと本書について話をしました。
彼曰く、プロダクトとして実現していく現実世界をソフトウェアに落とし込んでいくにあたり、クラスという概念が思考の整理のためにも、プロダクトを作り出していくプロセスとしても、はじめて意識をすることができたと言っていたことが興味深かったです。
ウォーターフォール開発全盛期の頃に、上流工程で決められたことを、オブジェクト指向UML等を通じてブレイクダウンしていく、お堅めで難しめなアプローチに見えていたクラス設計は、今のアジャイルのように不確実性をコードと共に具現化していくことが求められる文脈においては、もっと効果的な思考整理の手段として扱えるのではないかと思いました。
コンテキストが変わるとプラクティスが持つ価値観が変わる。
ドメイン駆動開発についても、10年ぐらい前に出会ったときと今ではそのことが持つ価値がそこそこ変わっている気がしており、面白いです。

若手エンジニアとの感想戦での学び

本がコンテキストに大きく影響を受けることを実感。
今のプロダクトのバックエンドは動的型付け言語で実装されているため、静的型付け言語の体験が薄いエンジニアにとって、Javaでの説明は身近な例とならないことを実感しました。
逆に言うと、ドメインに対する取り組みが今の開発からは構造的に捉えづらいことも想定が出来ました。
まずは、関心の分離や単一原則の法則にフォーカスして、実践することで理解を深めることが重要と思いました。チームとしても捉えていきたい。
次はTidyFirstを読むそうです。お片付けの方が即効性が高そう。
若手エンジニアの気づきや成長が楽しみです。

忘れたくないメモ

私が本書から受けた学びをもとにした気づきのまとめです。

ドキュメントが嘘をつきはじめる

スプレッドシートなどを用いた実装仕様書がつくられる場合があります。各クラスやメソッドの仕様を説明したドキュメントです。しかし、この手のドキュメントは忙しさなどからメンテナンスされなくなっていきます。コードの仕様変更にドキュメントのメンテナンスが追いつかず、 ドキュメントが嘘をつきはじめるのです。不正確なことが書かれているわけですから、後任の担当者は混乱し、バグを埋め込む可能性が増大します。
技術駆動命名や連番命名を用いると、ロジックが不必要に複雑化しやすいです。意図や目的を表現した命名をすることで構造が簡明になります

若手エンジニアの頃に携わったウォーターフォール開発では、こうしたプログラミング仕様書は当たり前のように存在していました。
私はSES契約で詳細設計から結合テストまでを担当し、その後そのプロダクトやプロジェクトに携わることはありませんでした。
ただ、我々がいなくなってもプロジェクトはしばらくは続いたし、プロダクトはもっと続いたと思います。
そうしたことを当時のウォーターフォール開発のプロジェクトでは誰も予期できなかったのだと思っています。

ドメインクラスの重要性

設計に無頓着だと、税込み金額計算ロジックが実装されていることにほかの担当者が気づかず、再実装してしまうことが多くなります。
このような事態はデータを保持するクラスと、データを使って計算するロジックが離れているときに頻発します。データと計算ロジックがそれぞれ遠く離れた箇所に実装されているために、計算ロジックが複数実装されていても、認知が難しいのです。

私は開発エンジニアとしての最盛期をスマホアプリのバックエンド開発のテックリードとして過ごしました。
自分が主軸となって開発をする上では、ここに書かれている「認知が難しい」ことは自分の脳みそで管理できていればそこまで大きな問題と思っていませんでした。
ただ、今ひとりの開発エンジニアとしてチームに所属し、「認知が難しい」の次元が違うことに気付きます。
常に機能を開発することを求められるプロダクトチームにとって、ソースコードレベルでの認知を揃えることは難しく、改めてドメインクラスの重要性、必要性を痛感します。

プリミティブ型に対する執着

プリミティブ型だけで「動くコード」を書くことはできるでしょう。しかしそれでは強く関係し合うデータとロジックをうまくカプセル化できません。このため、バグを埋め込みやすくなり、可読性が低下します。
データがただ存在しているだけ、というのはほとんどありえません。データを使って計算したり、データを判断して制御を切り替えたりするものです。プリミティブ型だけで実装しようとすると、データのありかとデータを使って制御するロジックのありかがバラバラになります。

値オブジェクトという概念を知らず、ひたすらにモデルクラスに引数がプリミティブ型のメソッドを量産していました。
nullが入る訳ないから、プリミティブ型で実装せねば~と猛進していた記憶があります。
恥ずかしい。当時書いたコードをリファクタしまくりたい。

単一責任の原則

同じようなロジックが複数あるからといって、責任を考えず無理にひとまとめにすると関心が混在してしまいます。

作り方ではなく、何を目的に使うかで判断をする。
使い方は目的を主軸に変わっていくので、目的ベースで処理を纏める。

目的駆動名前設計

プログラミングにおける名前の役割は、可読性を高めることだけではないと考えます。
業務目的に焦点を合わせた名前を付与することは、関心の分離を実現する上で重要です。設計上大きな意味があるため、「名前を設計する」といいます。
目的駆動名前設計は、ソフトウェアで達成したい目的や意図を、名前から読み取れるようにします。

ここで書かれていることを実現するためには、PBIの文章や設計書に書かれたことでは無く、要件の裏にある背景・業務を意識してプロダクトを開発する必要があると思っています。
それをチームで実現していきたい。

追記

変更容易性の重要性を説明する上で、開発生産性カンファレンスでのミノ駆動さんの登壇内容もよくチーム内で共有しています。

speakerdeck.com