|
||||
前回は、IOP(Inside-Out Principle)を説明し、ソフトウェアの設計を、 システム全体をレイアウトする「場」(アーキテクチャ)を作り、 そこに安定性の順序に従って抽象を切り出していく作業。 と再定義しました。アーキテクチャを安定性の順序、すなわちInside-Outで設 計する。まずモデルから、最後にユーザーインターフェイスを設計するという のが設計活動の大きな指針です。 今回は、後半の「抽象を切り出していく作業」についての原則を紹介します。 ここで、抽象(Abstraction)というのは概念とマッピングできるモジュールのこ とです。オブジェクト指向設計では、抽象をモジュール(ソフトウェア分割の 単位)と直接マッピングできるのが大きな利点なのです。 すなわち、「クラス」がこの抽象であり、かつモジュールの役割を果たします。 SRPは、どのようにシステムをクラス分割(発見、抽出)するか、に関する指針 です。 SRPでは、「1つのクラスは1つの責務を持つ」を原則とします。複数の責務を 1つのクラスに持たせないこと。1つの分かりやすい役割をクラス分割の境界 とすること。1つのクラス内に入る要素(属性や操作)が、1つの目的に向かっ て凝集していること。これが原則です。 70年代に、構造化設計の文脈においてPeter Code、Edward Yourdon、 Larry Constantine、Tom DeMarcoらがモジュール内の要素の結びつきを cohesion(凝集度)という名前で具体的に定義しています。凝集度のレベルを5 段階とし、より強い結びつきを持ったものをモジュール内に入れるという原則 を示しています。ここでの「モジュール」という言葉を「クラス」と呼びかえ ると、この原則は現在のオブジェクト指向の文脈でも十分に通用するのです。 さて、Robert C. Martinは、この原則をさらに現代的に言い換えています。 クラスに変更が起こる理由は、一つであるべき。 A class should have only one reason to change. 「変更」に焦点を当てた定義は、より具体的です。もし、変更の理由が2つあ る場合、そのクラスは2つに分割すべきだし、もし1つの変更が2つのクラス にまたがるなら、そのクラスは1つに統合すべきだと言っています。 この原則により、ある変更が起きたとき、その変更の連鎖を最小限に食い止め ることができます。この定義によって「アーキテクチャの連続性」と同じく、 変更に対して強い設計、という具体的なクラスの責務分割の指針が示されます。 最後に、本当によいクラスが抽出できたかどうかを簡便に判断する方法があり ます。それは、そのクラスに「よい名前が付けられるか」という基準です。 よい抽象には良い名前がつく。 A good abstraction has a good name. これは、誰もがいろいろなところで言っていますが、私もこの基準が本質的で あると考えています。良い名前であることは、SRPの本質です。 また、クラスの候補が見つかったら、良い名前を探してみることが重要です。 私は机上にシソーラス辞書(英語の類義語辞典)を置いており、よい名前を常 に探すことにしています(*1)。ぴったりくる名前を発見したとき、自分の発見 したクラスの輪郭がくっきりと浮かび上がってくるものです。そして、システ ム全体がクラス群に分割されたとき、その名前群が1つの意味体系を作り上げ て行くのが理想なのです。 * * * 先日、Tom DeMarcoの79年の著書(*2)に、名前に関する議論を見つけました。 意味あるモジュール名が思いつかないとき(「このモジュール何て呼ぶ」、 「太郎でどう」というような場合)は、まず、容認できない凝集度である。 たどりついた名前が中身のない名前だったり、多義の他動詞と目的語の組み 合わせだったら、これも容認できない凝集度である。1つの他動詞と1つの 目的語を持つ力強い名前にたどりつけば、そのモジュールは強く凝集してい ると言える。 「力強い名前」。わたしはこの言葉にはっとしました。 上記は構造化設計であるために、「1つの他動詞と1つの目的語」がよいモ ジュール分割の結論になりますが、オブジェクト指向では、「1つの名詞」が よいクラス名の、「1つの他動詞と1つの目的語」がよい操作名の典型例です。 今回は、クラス*内*の凝集度(cohesion)について話しをしました。次回は、ク ラス*間*の結合度(coupling)について話をしたいと思います。 |
||||
[1] これは、Ward Cunninghamがシソーラスパターンとして書いています。 [2] 『構造化分析とシステム仕様』、1979(邦訳 1986年、1994年新装版) |
||||
つづき |