書籍情報
タイトル | 改訂新版 良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方 |
著者 | 仙塲大也 |
出版 | 技術評論社 |
発売日 | 2024/12/25 |
ISBN | 978-4-297-14622-1 |
価格 | 3,200円+税 |
※本書は「改定新版」のレビューとなります。
概要と対象レベル
本書は設計をこれから学ぶ方向けに書かれた本です。
不具合を生み、プロジェクトに混乱をもたらす「悪いコード」の例を取り上げ、どのような弊害があるのかを解説し、良いコードへ改善する形で解説が進められていきます。不具合を起こしにくく、起こったとしても原因を究明しやすく、仕様変更にも柔軟に対応していけるコードを目指すための本です。
「入門」とありますが当然設計自体がそれなりに発展的な分野なので、文法レベルの解説はほぼありません。とはいえプログラミングの基礎を理解し、実際に開発を行っている方であれば新人からベテランまで幅広い方の助けになると思います。
なお、コード例としてJavaが使われていますが、現代のオブジェクト指向言語、特に静的型付け言語であればテクニックは他言語でも十分利用可能と思われます。
本書の主題
本書は全18章、約400ページ分量があり、多岐にわたる説明がされていますが、オブジェクト指向の3大要素(カプセル化、継承、多態性)をどう活用するか、特にカプセル化についてはどういう意義があるか、カプセル化する単位をどう決めてコードを適切に分離していくかは横断的に書かれており大きなテーマの1つになっています。
例えば本書では金額を表すMoneyクラスの実装が例として取り上げられています。
金額に関する処理では額をintで扱うかもしれません。ただintでは負値が入ってしまう可能性があります。通貨の単位(円、ドルなど)を表すこともできません。結果、不正値が入りやすかったり、それをチェックするコードがあちこちに書かれてしまいます。
そこで金額を表すクラスを作ろう、という発想になります。ドメイン駆動設計において値オブジェクト(Value Object)と呼ばれる概念です。コードをそのまま引用はできないので概念だけですが、以下のようなクラスを作るということです。
class Money
{
final int amount; // 金額
final Currency currency; // 通貨単位
// 以降、コンストラクタやメソッドで常に正しい値が入っていることを保証できるよう実装していく
}
このように実装されたクラスは非常に小さなものになります。本書では実際のプロダクトコードでも1クラスはせいぜい100行程度が目安とあります。
そこまで小さく分割されたクラス設計を現場では見たことがないという方もいるかもしれません(私自身の経験でもそうです)が、このように小さな単位で設計することで関心をクラス毎に分離し、各クラスで完全性を保証するというのが現代的な設計、本来のオブジェクト指向プログラミングであるといえます。
実際のプロダクトコードではMoneyクラスのように現実世界のもの(お金)に対応していて誰でも理解しやすい単位でクラスを設計できるとは限りません。単純にそのような観点でクラスを作ると次第に肥大化していき、100行どころか数百行、数千行とクラスが膨らんでいく例は非常に多いです。
ではどのような観点で分離していくか、というのは本書で「関心の分離」と呼んでいて大きな1つのテーマとなっています。
他にも条件分岐を整理する方法やコメントの正しい書き方、プロジェクトやチームの運用の方法まで「良いコード」を書くための多くの手法がまとめられています。
読了後の気づき
初心者向けとして書かれている本ではありますが、おそらく中堅、ベテラン層の方にとっても学びが多い内容ではないかと思います。
私も中堅と呼べるほどのキャリアとなり、良いコードを書こうということは常に意識しているつもりでしたが、設計についての基本的なところが理解できていないことにも気づきました。例えばクラスや関数を適切に、小さく分離するという視点は持っていましたが、先ほど取り上げた値オブジェクトぐらい小さな単位まではできていませんでした。
私は組み込みやPCアプリケーションの経験が長かったのですが、このような分野はどちらかというとレガシー気味な技術が多く、それに伴い実際のコードの構造も、エンジニアの知識としても新しいとは言い難い場合が多いように思います。もちろんケースバイケースですが、私レベルの知識でもこれまで普通に業務を行い、周囲とのコミュニケーションでもさほど齟齬がなかったのが現実を表しているのかなと思います。
そもそもオブジェクト指向でない言語が使われることもあるでしょうし(組み込みでは今だにC言語は現役です)オブジェクト指向が採用されていたとしても、カプセル化を正しく理解し、ポリモーフィズムまで適切に活用したコードというのは本当に少ないと思います。
モダンな環境の現場ではまた違うのかもしれませんが、私の経験の範疇ではオブジェクト指向の特徴を生かした設計よりも、手続き型的な古いパラダイムで実装されることが多いと感じます。
それが間違ってるというわけではなく、手続き型的なコーディングは誰でも理解できるというメリットがあります。設計というのは高度になるほど理解者が減るため、良い設計のコードが「このコードは理解できない、レガシーコードだ!」と言われるのを見たこともあります。
チーム個々人のレベルやバックグラウンドは様々でしょうから、技術的に高度で正しいことだけを実施するのではなく、理解をチームで共有するチーム作りも含めてやっていくことになります。
それは本書でも強調されており、重要かつ非常に難しい課題だと思いますが、それは設計に興味を持った自分自身が推進する以外ありません。
そうして継続的にチーム全体のレベルアップを図っていくことが他ならぬ自分自身のキャリアのためであると感じました。
読者のあなたは、少なくとも設計に関して課題を感じ、危機意識を持っているものと筆者は考えます。ぜひ設計責任者として立候補し、開発力の向上に貢献してほしいと筆者は願います。
第17章 設計を妨げる開発の進め方との闘い より
実際の現場への適用
こういった本を1冊読むと、現在関わっている仕事のコードの問題点がよく見えてきたりします。著者も悪いコードを見破る「目」を養うことの重要性を説いています。
今のコードをもっと良くしたいという気持ちが湧いてくるのは自然なことだと思いますが、一方で実際の開発現場で実施していくことは課題を感じる方も多いのではないでしょうか。
これも著者が述べていることではありますが、現場では設計の改善に対する反発があることもあります。せっかく動いてるコードを触らないでとか、理想論と切り捨てられてしまうとかです。
そこで、私が思うのは誰でもできることから始めよう、ということです。例えば以下のようなことです。
- コメントの改善(ほとんどノーリスク)
- 使われていないコードを消す(コンパイラ型であれば低リスク)
- 分かりにくいシンボル名を改善する(こちらもコンパイラ型であれば低リスク)
クラスの構造を変えていくなどはとても重要でありつつ、やはりそれなりに大変な話だと思います。プログラマ一人の一存でできることではないかもしれませんし、チーム全体の理解を得るにも時間がかかります。
本書では名前付けについても「名前設計」と題して細かく解説されていますが、そこまでいかずともまずは同じ構造のまま分かりやすい名前に変更する、ということでも改善活動の最初のステップとしては十分だと思います。
誰でも理解できて低リスクで実施可能なことから開始すれば効果の実感も得やすいですし、以降のもっと高度な改善へ向けたモチベーションにも繋がっていくと思います。
設計を学ぶ意義
本書と直接関係はありませんが、読んでいて設計を学ぶ意義についても改めて考えました。
世の悪いコードの量に比べ、それに問題意識を持つエンジニアの数も多いように思います。プロジェクトがうまくいかない時、設計が悪い(そもそも実施できていない)から改善すべきという意見が出てくることは多い印象です。
一方で、設計を体系的に勉強しているエンジニアの数は少ないように思います。設計が話題に出ると「自分の設計ではこうです」というように、チーム内で特に合意したわけではなかったり、独自の理論で設計を行っていることはよくあるように思います。
そういったことを否定するわけではありませんが、この場合他の人にとって理解しにくく、品質向上に貢献していないこともあります。
世の設計パターンというのはかつてのエンジニア達の知の集合です。私は設計においてはパターンとして実績が確立された手法を使うべきだと考えます。
アルゴリズムなどは性能が良ければ社内や個人独自の方法も採用されうると思いますが、設計は認識レベルを合わせるためにも定評のある方法を使った方が品質向上に貢献しますし、それこそが設計を学ぶ意義なのではないかと思いました。
さらなる発展へ向けて
本書は設計の入口であると著者は述べています。
内容は網羅的に書かれているため、本書をきっかけにドメイン駆動設計をもっと勉強してみようとか、テスト駆動開発や他のアーキテクチャの勉強をしたいというきっかけになるかもしれません。脚注で引用元が明確に述べられていたり、最終18章で良い書籍が多数紹介されています。
私も今後のキャリアをアップデートしてくためにも、継続的な学習をしていきます。
コメント