3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「改訂新版 良いコード/悪いコードで学ぶ設計入門」を読んで

Last updated at Posted at 2025-02-03

はじめに

「改訂新版 良いコード/悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方」を読みました。

昨年転職をして環境が変わり、同じ言語でも採用されているアーキテクチャが全然違うことを肌で感じつつ、改めて腰を据えて設計について基本からしっかり学び直したいなと思ったのが本書を読み始めた経緯です。

なお2025年の抱負の一つとして、月に1冊技術書を読むことを個人的な目標として掲げており、1月分がこの本でした(ちょっと足が出ましたが…)。

全体的な所感

本の中で、質の悪いコードにより作り出される悪い状況を総称して「悪魔」と呼んでおり、言葉の使い方に若干の抵抗を感じながらも最後まで読みました。

ですが、全体としては読んでとても良かったと思います。

まず、実際のプロダクションコードに取り入れられそうな考え方が多く見られた点が良かったです。

例えば、「継承より委譲を」という考え方や「インターフェイス設計」に関する考え方など。
この辺りは、後ほどもう少しだけ詳細を書きます。

次に、後半にかけての設計に臨む上でのメンタリティの部分。
開発者にとっての資産は「技術力」であり、レガシーコードはその成長を妨げる大きな弊害となり得る。
加えて、いきなり最良の設計には辿り着かないので、とにかくスモールステップで手を動かそう、という話。

そして、自分の1回の小さな追加・変更も、積み重なると取り返しがつかないレベルにまでコード全体を腐敗させ得る、という「割れ窓理論」の話。

当たり前のことだとは思いますが、改めて言われるとハッとしました。
日々心掛けていきたいと思います。

参考になった箇所のピックアップ

関心の分離

よく言われる事ですが、ソフトウェア設計においては「関心の分離」をすべきであるという話。
ここでの「関心」とはソフトウェアの機能や目的のことであり、目的毎にモジュールを独立させ、他の関心事と分離すべきであるという考え方。

目的駆動名前設計

上記の具体例として挙げられていた User クラスの話が参考になりました。

よく使われがちな User クラス。
これ自体が、複数の目的を無理やり一つに閉じ込めた「関心が混在したモデル」であるという話。

ユーザーという概念は非常に曖昧で、その中に「アカウント」「プロフィール」「法人/個人の区分け」など多くの関心事が一緒くたになっています。

ユーザーという「存在」ではなく、「目的」を主眼とすべきであるという内容に、ハッとしました。

また、巨大なデータクラスは、あらゆるユースケースで使われてしまうので、さながらグローバル変数の様相を帯びてしまう。

そもそもソフトウェアは仮想現実の世界であり、何らかの「目的」を実現するために組み上げられているもの。
無理に存在を表現しようとするのではなく、目的に即したモデリングをすべきであるという点は肝に銘じようと思いました。

継承より委譲を

「継承」はかなり注意深く扱わないと、あっという間に関心が混在してしまう。
そのため、基本的には利用を推奨しないという話は耳が痛い内容でした。

継承の問題点は、サブクラスがスーパークラスの構造に酷く依存してしまう点。

何重にも継承されてしまうと、関心はあちこち混ざり合い、手が付けられなくなります。

そうではなく、委譲を行いコンポジション(組み合わせ)構造にすべし。
利用したいクラスをスーパークラスとして継承するのではなく、private なインスタンス変数として呼び出すと良い、という話でした。

これも日々問題を痛感しているところなので、肝に銘じておきたいと思いました。

尋ねるな、命じろ

呼び出し側で複雑なハンドリングを行うのではなく、呼び出されるメソッドの側で複雑な制御を行うべしという話。
基本的なことですが、重要だと思ったのでピックアップしました。

インターフェイスと実装の分離

上記にも通ずる話ですが、インターフェイスとしてメソッドの仕様を外部に公開した上で、実装詳細とは分離すべしという考え方です。
これも基本的な考え方だとは思われますが、その大事さを再認識させられました。

例えば開発者が何らかのメソッドを使用したいとして、逐一内部仕様まで読み解いてから使用可否を判断するのではなく、インターフェイスとして定義された目的に即して使用を決める。
そうすることで、余計な認知負荷を減らすことができ、また変更容易性も高まる、という話です。

なお自分が前職で使用していた Go 言語などには interface 型が存在しますが、Ruby にはありません。

代用としては、「ダックタインピング」が紹介されていました。

ダックタイピングは参照記事を載せるに留まり、詳細は割愛しますが、改めて意識していこうと思います。
https://qiita.com/shimgo/items/9d9fbab1e3a7c4343f7b
(ダックタイピングの概要:特定のクラスと結び付かない暗黙的なインターフェイスの定義で、振る舞いに着目する考え方。)

おわりに

色々と参考になるところはあったものの、他の方の書評を読んでいると賛否ある部分もあるようです。
私自身も、書かれていたことをそのまま鵜呑みにするのではなく、今後も他の技術書を読み、実際に手を動かしながら考えを深めていきたいと思います。

自分自身の振り返り用として書いた部分も大きいですが、少しでも読んでくださった方の気付きになりましたら幸いです!では!

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?