第12章 メソッド(関数) ―良きクラスには良きメソッドあり
この章では、メソッドの設計がクラス設計の質に大きく関わること、そしてその逆もまた然りであるという原則から始まる。メソッドは単なる処理の集まりではなく、オブジェクト指向における振る舞いを担う重要な構成要素であり、良いクラスには必ず良いメソッド設計があるという前提に立って、様々な観点から設計指針が述べられている。
12.1 必ず自身のクラスのインスタンス変数を使うこと
原則として、メソッドは自身のクラスのインスタンス変数を使って動作すべきである。他クラスの状態を変更するような構造は低凝集を招くため避けるべきだ。
実際の開発でも、他のクラスのフィールドを無理に操作しようとして設計が崩れることはよくある。インスタンス変数の操作は、その変数を保持するクラスに委ねる方が責任の所在が明確になり、安全性も向上する。
12.2 不変をベースに予期せぬ動作を防ぐ関数にすること
メソッドが可変な状態を変更すると、その影響範囲が予想しづらくなり、バグの温床になる。不変な設計にすることで堅牢性が増し、保守性が格段に向上する。
予期しない副作用によって挙動が崩れる体験は誰しも経験があるだろう。後からその理由をコード中に探すのは非常に骨が折れる作業である。不変性を前提にした設計を心がけたい。
12.3 尋ねるな、命じろ
「尋ねるな、命じろ(Tell, Don’t Ask)」という設計原則が紹介されている。他クラスの状態を取得し、その結果に応じて処理を変える構造は、凝集度が低くなる傾向がある。
この章では特に getter / setter に対する警鐘が鳴らされており、データを自由に操作できる構造は危険だとされている。代わりにカプセル化を徹底し、必要な操作だけをメソッドとして公開すべきである。個人的にも、ビジネスロジックが外に漏れる設計は極力避けたいと常々感じている。
12.4 コマンド・クエリ分離
CQS(Command Query Separation)は、メソッドは「状態を変更する」か「状態を返す」かのいずれか一方に限定するという設計原則。コマンドとクエリを同時に行う「モディファイア」は避けるべきとされる。
副作用があるのかどうかが曖昧なメソッドは読み手を混乱させ、テストや保守の負担も増える。コードを読む際にも「このメソッド、値を返してるけど副作用あるのかな…?」と警戒することが多いため、こうした原則は実務において非常に重要である。
12.5 引数の扱い
引数に関する設計の注意点が丁寧に述べられている。以下がポイントだ。
- 引数は不変にすること
- フラグ引数は使わない
- null を渡さない
- 出力引数を使わない
- 引数は可能な限り少なく
null やフラグ引数は実装者の意図がコードから読み取れず、メソッド内部を開いて確認する必要が出てしまう。ストラテジパターンなどの活用で機能の切り替えを明示することが推奨されている。
日頃から引数に null
を使ってしまう場面はあるが、意味を持った状態として設計し直す努力が必要だとあらためて感じた。特にPHPのように null
が簡単に使える言語では、安易な選択肢として流れてしまいがちなので意識して避けたい。
12.6 戻り値の設計
戻り値にも多くの設計配慮が求められる。主な原則は以下の通り。
- プリミティブ型ではなく、型で意図を明示する
- null を返さない
- エラーは戻り値ではなく例外でスローする
エラーを戻り値で表すと、ダブルミーニング(二重の意味を持つ)状態となり、呼び出し元がそれを知っていないと誤動作を招く可能性がある。これにより分岐処理があちこちに散らばり、複雑さが増す。
私自身も、値の戻し方を簡単に済ませたくて null を返したり、状態コードを戻した経験がある。しかし後から見返すと、解釈が難しくバグの温床になっていたことを痛感している。
メソッド名の設計
「動詞+目的語」の命名は、一見わかりやすいようでいて、責務を超えるロジックを抱えがちである。理想は、動詞1語で完結するようにクラスとメソッドの設計を合わせること。
この視点は実際に設計を考える上で非常に参考になる。メソッド名が長くなるときは、そもそもその処理が1メソッドに収まるべきなのかを見直すきっかけになる。
static メソッドの扱いに注意
static メソッドは、凝集度が下がるため使用には注意が必要であり、限定的な用途(ファクトリメソッドやユーティリティなど)に留めるべきである。
便利だからと多用してしまうと、オブジェクト指向の利点が活かせなくなり、疎結合な設計が崩れてしまう。適材適所で使いたい。
まとめ
メソッドの設計は、単に動くコードを書くこととはまったく次元の異なる行為である。クラスとメソッドの責務を明確に分け、不変性を保ち、状態やデータの扱いを慎重に考えることで、コードは驚くほど保守しやすく読みやすくなる。
引数や戻り値の扱い方、命名の仕方、設計上の原則など、どれも実務での悩みどころを的確に突いており、改めてメソッド設計に向き合う良いきっかけとなった。