『オブジェクト指向設計実践ガイド』の「第2章:単一責任のクラスを設計する」のまとめです。
ポイント:「クラスに属するものをどのように決めるか」
・クラスを使い、"今すぐに"求められている動作を行い、かつ"あとにも"かんたんに変更できるようにする
・設計とは、アプリケーションの可変性を保つために技巧を凝らすことであり、完璧を目指すものではない
変更がかんたんなようにコードを組成する
1.変更は副作用をもたらさない
2.要件の変更が小さければ、コードの変更も相応して小さい
3.既存のコードはかんたんに再利用できる
4.最もかんたんな変更方法はコードの追加。ただし追加するコードはそれ自体変更が容易なもの
どんな性質のコードを書けばいいか?
「変更がかんたんなコード」の定義を受けて、実際にコードを書くときには「TRUEなコード」を心がける。
1.見通しが良い(Transparent):変更がもたらす影響が明白
2.合理的(Reasonable):かかるコストは変更がもたらす利益にふさわしい
3.利用性が高い(Usable):新しい環境、予期していなかった環境でも再利用できる
4.模範的(Exemplary):コードに変更を加える人が、上記の品質を自然と保つようなコードになっている
・TRUEなコードを書くための最初の第一歩は、「それぞれのクラスが、明確に定義された単一の責任を持つように徹底する」こと
単一の責任を持つクラスをつくる
・クラスはできる限り最小で有用なことをするべき -> 単一の責任を持つべき
・クラスになるにふさわしいもの -> 「データ」と「振る舞い」
Q.なぜ単一責任が重要なのか
A.2つ以上の責任を持つクラスは、アプリケーションが予期せず壊れる可能性があるから
->変更が加わるたびに、クラスに依存するクラスを全て破壊する可能性がある
クラスが単一責任かどうかを見極める
Q.あるクラスが、別のどこかに属する"振る舞い"を含んでいるかどうかを見極める方法は?
A1.あたかもそれに"知覚"があるかのように仮定して問いただす。
->クラスの持つメソッドを質問に言い換えたときに、意味をなす質問になっているべき
例)「〇〇クラスさん、あなたの××を教えてください」 <-理にかなった質問になっているか?
A2.1文でクラスを説明したときに、「それと」「または」が含まれない
・「クラスでできる限り最小で有用なことをすべき」 => 「かんたんに説明できるものであるべき」
・「それと」が含まれる => おそらく2つ以上の責任を負っている
・「または」が含まれる => クラスの責任が2つ以上あるだけでなく、互いにあまり関連しない責任を負っている
設計を決定する時を見極める
・「早い段階で設計を決定しなければ」という気持ちに駆られるのはダメ
・何もしないことによる将来的なコストが今と変わらない時、設計の決定は延期する
・決定は必要なときにのみ、その時点で持っている情報を使ってする
単一責任の概念はクラス以外のコードでも役立つ
メソッドから余計な責任を抽出する
・単一責任にすることで、メソッドの変更も再利用もかんたんになる
・メソッドに対しても、役割がなんであるか質問をし、また1文で責任を説明できるようにするとわかりやすい
・「単に振る舞いを別のメソッドに分離する」リファクタリングは、最終的な設計がわかっていない段階でも実施すべき
単一責任のメソッドがもたらす恩恵
1.隠蔽された性質を明らかにする
2.コメントをする必要がない
3.再利用を促進する
4.他のクラスへの移動がかんたん
1.隠蔽された性質を明らかにする
クラス内のメソッドを他のクラスに再編する意図がなくても、それぞれのメソッドが単一の目的を果たすようにすることによって、クラスが行うこと全体がより明確になる
2.コメントをする必要がない
もしメソッド内のコードにコメントが必要な部分があれば、その部分のコードを別のメソッドに抽出する。
別のメソッドに抽出した新しいメソッドの名前が、コメントの目的を果たす。
3.再利用を促進する
メソッドを小さくすることで、アプリケーションにとって健康的なコードの書き方を促進する。
4.他のクラスへの移動がかんたん
設計のための情報が増え変更をしようと決めたとき、小さなメソッドならかんたんに動かせる。
移動のためにいくつものリファクタリングやメソッドの抽出もする必要がない。
クラス内の余計な責任を隔離する
・いったん全てのメソッドを単一責任にしてしまえば、クラスのスコープはより明白に
・単一責任にこだわり、余計な振る舞いをそのクラスに「あるorない」の二択にするのは短絡的すぎる
⇨設計の目的は、設計に手を加える数を可能な限り最小にしつつ、クラスを単一責任に保つこと
⇨普段から変更可能なコードを書いておくことで、どうしてもしなければならない時まで決断を先延ばしすることができる
終わり
単一責任とか、ただ書籍で読んで知った知識はなかなか理解できないのですが、ちょうどこの章を読んでいるときに自分の初めて作ったサービスのコードを思い出しました。
それはメソッド部分だったのですが、コードを読み直すと明らかに単一責任ではない部分があったので実践しました。
明らかにメソッドもシンプルに、かつ読みやすくなったと思います。
書籍から学ぶ場合も、勉強したことをすぐに取り入れるのは効率的な学習をするためにも必須ですね。