巨大な衝撃
マーティン・ファウラー著:1997年11月/12月号『分散コンピューティング』掲載コラム
あるクライアントとオブジェクトモデルレビューについて話していました。「事前にドキュメントを送付できますが、役に立ちますか?」と彼らは尋ねました。私は肯定的に答えましたが、嘘をついていないことを願っていました。2日後、UPSの配達員が私のドアの外に荷物を届け、大きな音を立てました。それは厚さ3.8cmほどのドキュメントでした。
それを開けてみると、CASEツールから出力されたプリントアウトが入っていました。いくつかの図表が示されており、すべてのクラス、属性、操作について詳細な説明が書かれていました。これらすべてに定義がありました。Contractクラスは「多くの当事者間の契約」と定義され、dateSigned属性は「契約が締結された日付」と定義されていました。私は3.8cmのドキュメントを読み通しましたが、結局ほとんど理解できませんでした。オブジェクトが何かについては多くの記述がありましたが、それらが何をするためにあるのかについての説明はほとんどありませんでした。これは初めてのことではなく、これが最後になることはないと予想しています。
なぜモデルやドキュメントに苦労するのでしょうか?それらは実行されませんし、顧客は美しい絵ではなく、動作するコードに対して支払いをしています。モデルに苦労するのは、コミュニケーションのためです。グラフィカルなオブジェクトモデルは、ソースコードを見るよりもオブジェクトがどのように連携しているかをより明確に示し、インタラクション図は、複数のクラス定義から呼び出しパスを推測するよりも、協調動作をより良く示すという考えです。しかし、設計ドキュメントはしばしばこの点で失敗し、私をソファで困惑させます。
問題の一部は、人々がこの種の作業に使用しているCASEツールです。(CASEツールには、ドキュメント作成とコード生成の2つの目的があり、ここでは前者の役割についてのみ言及しています。)CASEツールは辞書的な考え方をかき立てます。各クラスのエントリを作成し、図表にすべてのクラスと属性を表示し、各ユースケースのインタラクション図を描画します。「すべてを文書化しましたか?」という質問に答えることで、完全主義を促進します。
しかし、それは間違った質問です。すべてを文書化すると、すべてに同じ重みを与えてしまいます。複雑なシステムに対してそれを行うと、詳細に埋もれてしまいます。どのシステムにも、他のものよりも重要な側面があり、一度理解すれば、より多くのことを学ぶのに役立つシステムの重要な側面があります。ドキュメント作成における技術は、これらの側面をできるだけ明確に文書化する方法を見つけることです。これにより、これらの領域を強調し、詳細をコードに残します。
何よりも、このドキュメントは簡潔でなければなりません。簡潔な場合のみ、人々はそれを読んで理解します。簡潔な場合のみ、最新の状態に保つことができます。すべてについて話すことはできませんし、するべきでもありません。友人の一人から、クラス名を変更することに消極的だったプロジェクトについて聞きました。コードの変更に時間がかかりすぎるのではなく、ドキュメントの変更に時間がかかりすぎるためです。ドキュメントが問題になると、対処する必要があります。少なくとも半分は捨ててください。
何を言うべきですか?
何を表示するかをどのように選択すればよいでしょうか?残念ながら、それはあなたの専門的な判断に委ねられています。あなたを導く規則はありません。設計者とコミュニケーション担当者としてのあなたのスキルだけです。おそらく、人々がすべてを表示しようとするのは、何が不要かを決められないからでしょう。したがって、現時点での私のアプローチを以下に示します。システムが妥当な規模であれば、システムをパッケージ(UMLやJavaのように)に分割します。各パッケージは、特定の目的のために連携する一連のクラスで構成されます。パッケージとその依存関係を示す図を使用して、システムの全体構造を文書化します。(UMLでは、これはクラス図の特定の用途ですが、私は頻繁に使用するため、パッケージ図と名付けるのが好きです。私の著書『UML Distilled』を参照してください。)設計を使用してこれらの依存関係を最小限に抑えましょう。これは、システムのカプリングを最小限に抑えるための鍵です。(これを行う方法については読むべきものがほとんどありません。私が知っている最良のものは、Robert Martinの『Designing Object-Oriented C++ Applications Using the Booch Method』です。)
各パッケージについて、簡単なドキュメントを作成します。ドキュメントの基礎は、パッケージが実行する主要なタスクとその方法について説明するいくつかのナラティブテキストです。UML図を使用してこれをサポートできます。パッケージ内の重要なクラスを示すクラス図を描画しますが、必ずしもすべてのクラスを示す必要はありません。各クラスについて、重要な属性と操作のみを表示し、すべてを表示しないでください。実装ではなくインターフェースに集中します。パッケージ内の重要なコラボレーションごとに、インタラクション図を示します。クラスに興味深いライフサイクルの動作がある場合は、状態図で示します。ドキュメントは、最新の状態に保つことが問題にならない程度に小さくする必要があります。通常、私は12ページ以内にするように心がけています。
パッケージごとのドキュメントに加えて、コラボレーションがパッケージにまたがってどのように拡張されるかを示すことも役立ちます。そのためには、システム内の主要なユースケースを特定し、インタラクション図とナラティブを使用して文書化します。関連する主要なクラスを強調表示するクラス図も役立ちます。多くの人が、システムのすべてのユースケースのインタラクション図を描くことを推奨しています。私は、これによりドキュメントが多すぎる可能性があると感じています。しかし、それが役に立つと感じ、最新の状態に保つことが問題ない場合は、実行してください。それでも、誰もが理解する必要があるものとして、強調する主要なユースケースを12個以下に限定する必要があります。
コミュニケーションが鍵
この記事全体を通して、コミュニケーションを強調しています。CASEツールについて少し批判的に述べていますが、それは主に、ツールを使用するだけではコミュニケーションしているわけではないという意味です。どのツールもコミュニケーションを促進または妨害する可能性があり、使用方法によって結果が決まります。
私が知っているプロジェクトでは、開発者が自分のワークステーションからアクセスできるマルチユーザーCASEツールを購入しました。すべての設計はCASEツールに入力する必要があります。しかし、すべての開発者がそれを使用できるからといって、すべての開発者がそれを使用するとは限りません。実際、非常に少数の開発者だけがCASEツールのモデルを見ており、さらに少数の開発者だけがそれを理解していました。これを実現して、プロジェクトのアーキテクトはオフィスで壁のスペースを確保し、システム内の重要なコラボレーションを6つ示す一連の図表で覆いました。彼はオブジェクト図を使用して、何が起こっているかを強調するためにカラーコーディングを使用してそれらを説明しました。すべての開発者がすべての設計を理解するという意味ではありませんが、少なくとも重要な要素が何であるかを確認できるようになりました。
この記事を書き始めたとき、私が話すことができることに圧倒されました。多くの逸話やヒントが思い浮かびました。しかし、この記事を読んでもらい、覚えてもらうためには、その中のいくつかについてしか話せないことを知っています。言及する必要がある重要なものを選択する必要がありました。コミュニケーションはすべてそれについてです。良いコミュニケーションの鍵は、言うべき重要なことを強調することです。すべてを言うことはコミュニケーションではありません。それは単に重要なものの選択をあなたの読者に委ね、重いドキュメントで彼らを落胆させます。情報の選択はコミュニケーションの最も重要な部分の一つであり、それはすべての設計者の責任です。