今回も引き続き、仙塲大也さんの「良いコード/悪いコードで学ぶ設計入門」を読んだ内容を、自分なりの理解も含めて少しずつ整理していきます。
参考書籍:
良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方
前回はこちら👇
今回読んだ内容
今回は「10章 名前設計-あるべき名前を見破る名前-」を読みました。
ここではクラスや処理が巨大化・複雑化し密結合になると、仕様変更時、いつも以上にバグへの注意を払う必要があったり、影響範囲が広くなって開発効率性が下がるという話がされていました。
その上で、適切な責務を考え、密結合を防止するために重要なポイントとして、クラスやメソッドへの名付けが紹介されていました。
本章では「目的駆動名前設計」という考え方を基本として進められていました。
読む前の認識
名前の付け方を考える際、
- 他の人が見て意味がわかるか
- 長すぎる名前になっていないか
を意識することが多く、特に後者についてはできるだけ短くできる命名にしようという考え方を持っていました。
一方で、その名前が示す責務や関心事の範囲が適切かどうかという観点ではあまり考えられていなかったように思います。
しかし本書では単にわかりやすい名前をつけるだけでなく、その名前が何を表し、どこまで責務を持つべきなのかを考える重要性が説明されていました。
また名前の長さについては、意図が伝わりにくくなるなら無理に省略せず、
名前から目的や責務を読み取れることを優先するという考え方も紹介されており、
「名前は短いほうが良い」という思い込みを見直すきっかけとなりました。
その中でも私は、名前設計を考える上で特に重要なのが、「関心事を分離すること」だと感じました。
なぜ関心事の分離が重要と感じたのか
本章の中では、良くない名前のユースケースに触れながらそれぞれ改善方法が挙げられていました。
その中で紹介されていた解決策の多くは、関心事を適切に分離することで実現されているように感じました。
例えば本書では、「商品」というクラスが挙げられていました。
ECサイトでは商品を中心に成り立っていますが、その周りには複数のユースケースが紐づいています。
ここでは、予約・注文・発送・出品の4つの関心事が挙げられていました。
これをそのままクラスとして括ると、商品クラスの中に複数の関心事が混在することになります。
本書ではこのような状態がクラスの肥大化につながり、仕様変更時の影響範囲を広げる要因になると説明されていました。
そこで必要になるのが「関心事の分離」です。
「予約」「注文」「発送」「出品」のような異なる目的ごとに整理することで、それぞれの責務が明確になり、目的に合った名前をつけやすくなります。
本章で紹介されていたアプローチ
ここでは自分が特に意識しようと思った点をピックアップします。
他の点についても気になる方はぜひ本書を読んでみてください。
1. 可能な限り具体的で、意味範囲が狭い、目的に特化した名前を選ぶ
筆者が「目的駆動名前設計」の中で最も重要なポイントとしていた点です。
これを意識することで以下のような効果があります。
- 名前と無関係なロジックを排除
- 目的と外れた関係クラスの個数も減らすことができ、結合度が下がる
=>上記により、仕様変更時の影響範囲が縮まる他、目的に特化した名前なのですぐにどこを変更すればいいかわかるようになり、開発効率の向上につながります。
2. ロジック構造をなぞった名前にしない
これは個人的にやりがちだと感じました。
自分の業務だと以下のような条件が出てくることがあります。
- 特定の帳票が承認済み
- ログインユーザーに権限がある
- 取引先の宛先が登録済み
ロジック構造をそのままなぞった名前にしてしまうと、極端な場合
const isApprovedAndHasPermissionAndDestinationRegistered
のような名前になってしまいます。
これだと長くて、何のための関数なのかぱっと見でわかりません。
ここで示したいことは、取引先に送付可能かどうかです。
なのでこの場合は
const canSendDocument
のような名前にすると目的がわかりやすくなります。
重要なのは条件を並べることではなく、その判定によって何を表したいのかを名前にすることです。
3. 名前を省略しない
「2.ロジック構造をなぞった名前にしない」では、canSendDocumentのような目的に合わせた名前にすることでなんのための値なのかが認識しやすくなるという話をしていました。
以前、名前はなるべく短い方が読みやすいのでは?と考えてどんどん短くしようとすることもありました。
ですが、isReadyやcanSendだけのようにすると、何の準備ができたのか、何を送るのかが曖昧になってしまいます。
そうすると、次にそのコードを見た人がまだそのシステムに詳しくなかった場合に、なんのための準備なのか調べる時間が発生してしまいます。
そのため、名前を省略したい場合はその省略名で本当に目的が伝わるかということを考えてつけていこうと考えました。
今後意識したいこと
本章を読んで、命名は単にわかりやすい名前をつける作業ではなく、責務や関心事を整理した結果として行うものなのだと感じました。
今後はクラス名や変数名を考える際、
- このクラスや変数の目的は何か
- 複数の関心事が混在していないか
- ロジック構造ではなく目的を表現できているか
- 省略により意図が失われていないか
を意識していきたいです。
また既存コードの修正を行う際も、単に命名を見直すのではなく、責務の分離や関心事の整理の観点からコードを改善できないかという視点も持ちながら向き合っていきたいです。
名前に迷ったときは命名ルールを探すのではなく、まずその処理やクラスが何を目的としているのかを考えるところから始めてみようと思います。