- ルーチンの作り方に指針がない。
- どんな風にルーチンを構成するとよいルーチンになるのかがわからない。
- 抽象化という単語は知っているが、抽象化された状態がどんな状態なのかわからない。
ルーチンの中には関連性の高い処理をまとめましょう。その状態を凝集性が高いと呼びます。
凝集性には許される凝集と許されない凝集があります。
許される凝集には、
- 機能凝集 (ルーチンがただひとつのことを行い、それ以外のことを行わない)
- 順序凝集 (ルーチン内の処理がルーチンをまたいで特定の順序で処理されなければならない関係にある。また、それぞれの処理で特定のデータを共有する)
- データ凝集 (ルーチン内の複数の処理が同じデータを使用する関係にある)
- 仮凝集 (同じタイミングで行われる処理をまとめてルーチンとしたもの。処理同士の意味的なつながりは薄い)
があります。
一方、許されない凝集には、
- プロシージャ凝集 (ルーチン内の複数の処理が特定の順序で処理されなければならない関係にある。また、それぞれの処理で扱うデータが異なる)
- 論理凝集 (ルーチン内の複数の処理の中から実行する処理をフラグで制御するもの。制御フラグは引数として渡される。実装としては if/case 文による条件分岐となる)
- 暗合的凝集 (ルーチン内の処理にどのような関係があるか判断できないカオス状態)
があります。
もっとも理想的な凝集は、機能凝集です。機能凝集では、ルーチンがただひとつのことだけを行い、それ以外のことを行いません。
許されない凝集の中で特に注意をしたいのは、論理凝集です。これは、ルーチン内で複数の処理をする予定があり、その実行する処理をフラグで制御するようなものを指します。制御フラグは主に引数として渡されます。(実装としては if/case 文による条件分岐として表現されます。)
また、論理凝集と区別すべきものに、if/case 文による条件分岐でその後の処理を制御するディスパッチャの役割を持つルーチンがあります。
ルーチンに制御自体(制御だけ)を役割として持たせ、実際の処理は別のルーチンを呼び出して処理するのであれば問題は少なくなります。
その場合、名称に Dispatch や Dispatcher を入れて、その役割を明示すると意識的に設計しているのが伝わります。
上記のように条件分岐を行う場合は、if 文の3つの役割を意識するとよいでしょう。
if 文の3つの役割とは、
- バリデーション
- ルール
- フロー制御
です。
バリデーションは、主にルーチンの事前条件チェックとして使われます。ルールは、「○○の場合、□□されなければならない。」というような仕様として表現されます。フロー制御は状態により処理の流れを変える役割を持ちます。論理凝集のところでディスパッチャとして説明したような処理を指します。これは多くの場合に処理を制御するフラグとペアで使われます。
暗号的->暗合的でしょうか?