我々はいかにシステム開発におけるドキュメント腐る問題と戦えば良いのか

フューチャーアーキテクト(裏) Advent Calendar 2017の3日目です。

はじめに

ITシステム開発には、設計書とコードの整合性を保つという苦難がありますよね。ウォーターフォールであれアジャイルであれ、ある一定数以上の開発者とシステム(アプリ)規模になると、どうしてもコードから全てを読むことは難しくなり、コード以外に全体観を把握できるドキュメントが必要になってくると思います。しかし、システムは生き物。常に変わりゆくものです。そんなシステムを示したドキュメントはしばしば、メンテナンスを後回しにされ、陳腐化(≒腐って)してしまいます。

ということで、Qiitaの別記事から引用しますが、ドキュメント腐る問題とは下記のようなことを示すことにします。

ドキュメント腐る問題とは、設計時に作成した各種ドキュメントがGoogle Driveやファイルサーバ上で陳腐化してしまい、現状の正しい状態を指していないことです。せっかく新規参画者がキャッチアップしようとしてもドキュメントが真実を示していないという怖いやつですよね。

今まで出会った一番辛いドキュメントは、PJ初期に作成したホワイトボードに書かれたラフスケッチの画像しか無かったところですね。まず字が汚いし、内容も最新版と微妙に異なっていました。新規参画者殺しにもほどがあると、ほんのちょっとだけ恨みました。

いやいや、ちゃんとサボらず整合性を取れよって?

サボらず整合性を取れよと一笑するのは、開発現場の苦しみをあまり知らない人でしょう。そもそもソースコードとドキュメントの整合性を取ることは非常に大変な作業です。また、常にハードな締め切りの中、課題に対してどういう解決方法が一番スマートか周辺システムを含めて調査し、解決案に対しての影響度範囲と費用対効果をバランスした上で技術判断し、コードを修正し、ユニットテストからステージング環境まで含めた品質チェックを行い、そしてなるべくユーザと既存システムに影響を与えないようにプロダクション環境にデプロイするのです。場合によってはそれぞれのフェーズでステークホルダーに説明が求められますし、政治やお金の問題で別のアプローチへの突然の変更もありるでしょう(もちろん、しばしばスケジュールの期限は変わらずに)。

システム開発は常にトレードオフの世界です。金銭的なコストと、ユーザに直接影響を与える部分は大体の場面において、優先度高だと思います。逆に開発ドキュメントは直接的に今すぐ影響を与えるわけではないので、もし機能改修とドキュメント保守のどちらかを選択しなければならない時、リーダーが開発を優先しドキュメントを保守後回しにする判断をすると思います。分かる、仕方ない。

取り残されたドキュメントはいつメンテされるの?

一度、陳腐化した設計ドキュメントを復活させるのはハードシングスです。そもそも、開発者はドキュメント整備を嫌がりますしね。来るかどうか分からない新規参画者や、ナレッジの横展開のためにドキュメントを整備するのはよほど夢と希望に溢れている人でしょう。非常にレアな人財だと思います。

また、実際問題どこがどう陳腐化しているのかよくわからないというのはよくあります。鉄は熱いうちに打てといいますが、終わってしまうとイマイチ修正する気が湧かないのは人間心理として仕方ないことかなと。

どうする…?

現場で役立つシステム設計の原則にあるUMLをPlantUMLで書いてみるでかなり説明しましたが、MarkdownやAsciiDoc、UMLはPlantUMLやmermaid、ERDはPlantUMLやerd、画面遷移図はUI Flow、REST-API設計はSwaggerなど、なるべくテキストベースで管理し、GitHubなどのリポジトリで管理することで、(レビューフローなどを適切に設定した上で)コードとの乖離を防ぐ、といったことが一案としてあるかと思います。

モデリングツールで行える表現の限界もありますが、コードとパワーポイントやExcelでの同期をとるのは、経験上ですがとてもパワーが必要なことなので、それに比べかなり実現性が高い案だと思います。また、個人的にはパワーポイントなどの資料作成能力は、センスが磨かれるまで時間を要したり、嫌いな人はメンテをとことん嫌がります。その点、テキストベースだと誰が書いても、同じ設計図が出力されるので効率的だし、パワポ図形のポインタがよく見ると微妙に繋がっていないなど、雑に作成されないという安心感があります。

他の案としては…

  1. ドキュメントからコードを生成する(自動生成案)
  2. ドキュメントはコードを元に生成する(リバース生成案)
  3. DSL定義などから、コードとドキュメントを生成する(DSL説)
  4. 整合性をがんばって取る
  5. そもそも陳腐化するドキュメントは作らない
  6. 陳腐化することは諦める

等があるかと思います。特に5,6はネタっぽいですが割りと本気です。陳腐化するくらいならいっそ作らないとか、もうメンテしないと割り切るほうが精神的にも安心です。

1. ドキュメントからコードを作る

昔からある伝統的な技法ですね。コーディングレスでシステム構築が出来るという浪漫があります。実際は独自な設定方法を覚えさせられたりそのツールごとの癖があるのですが、上手くハマれば強力そうですよね。

内部的には、外部定義ファイルを読み込んで挙動を変える巨大なルールベースプログラムになっていることが多く、けっこう出来ること出来ないことがハッキリとしてますよね。出来ない場合は個別のカスタマイズするためプログラムを開発する必要があったり、それは良いのですが、まずその結論にいくまで苦労して時間がかかることが不満のもとです。結論がすぐわかればよいのですが、そうでもなく、結局個別開発かよと肩透かしになるので、けっこうストレスフルです。実際に開発の矢面に立つ人や導入の責任者は大変ですよね。逆に超絶内部に詳しい人がチームメンバーにいるととても良いソリューションに思えます。

部分的にでもドキュメントからコードを作るのは良いですね。パラメータファイルとか、コンフィグファイルとか、テーブル定義のDDLやJSONとか。こじらせると、AnsibleやTerraformのスクリプトすらドキュメント生成するという、一体プロビジョニングツールを何だと思っているんだというレベルにまで到達しますが、ある意味清々しくて立派です。

手堅いのですが、このレールに乗せるまでが非常に苦労するので、ここらへんの初期構築が上手いプロダクトや、ナレッジがある組織は強そうです。

2. ドキュメントはコードを元に生成する

クラス図やERDはもうこれで良いんじゃないですかね。AWSだとIAMやSecurity Groupなど、リバースして定期的に見直すとか。

ただ、リバース生成系はかなりディテールのところまで出力されてしまい、ある程度デフォルメしたモデル図にはならないので難しいところです。Javaのクラス図くらいならリバースで出力しているところも多いのかな..?

ある意味、実機が正だよみたいな前時代的な前提を置いているので、モダンな開発現場だとあまりないかもしれません。今まで作成していなかったドキュメントを作るにあたって、初期バージョンとしてリバースすることは別として。

3. DSL定義などから、コードとドキュメントを生成する

SwaggerではAPI定義をYAML形式で行います。こうした定義から、API定義をHTML(やそこからPDF)に出力できますし、同時にバリデーションやコンバートコードを対応しているプログラミング言語で自動生成することができます。

DSL定義はシンタックスハイライト・フォーマッター・プレビュー表示・Linterが対応していることも多く、開発生産性が高いことも多いので積極的に導入したいですよね。APIはRESTじゃなくてgRPCやGraphQLだからって人も多そうですが、その場合はその場合で別のDSL定義がありそうですし。

4. 整合性をがんばってとる

その場合は人でがんばるのは不可能なので、コードとドキュメントの整合性をチェックするスクリプトが必要になってきます。CIなどで継続で気にLintを走らせるようなイメージでしょうか。

5. そもそも陳腐化するドキュメントは作らない

ドキュメント関連に頭をウンウンするのは勿体無い。いっそ作らなければ良いんですよ。価値を生むのはあくまで動くコード。ドキュメントに極力コストをかけないという案。意外とハマります。抽象度の高いポリシーやシステムアーキテクチャ図あたりは書いてしまって、そこから下は何も書かない、とか。

逆に陳腐化しないドキュメントは作るとも言い換えられます。現場で役立つシステム設計の原則にあるUMLをPlantUMLで書いてみるではPlantUMLや mermaidなど、テキストベースで管理(=リポジトリ管理)できるものは、レビューフローを整備した上でコードと同期を取ると話しましたが、同期をとるためのツールとフローがあるのであれば、そこはがんばれますし、がんばったほうが良いでしょう。

保守範囲がこういった設計ツールで表現できる内容が上限ですが、UMLで表現できる範囲内であれば大体がテキストベースで管理できるので、すなわちコードと同じ管理フローが取れ、同期をとりやすいです。

6. 陳腐化することは諦める

これも有力な案です。もうメンテナンスは気にしない。最新版が現実と近いと割り切るとか。どのみち、新規参画者もそこまで詳しいことを最初からキャッチアップしきれませんよ。最悪、陳腐化していそうなところだけ、「要修正」と補足するオブジェクトを被せるとか。ぶっちゃけ、陳腐化している部分だけわかれば読み手的にはその覚悟でドキュメントを読み込むので、多くの場合は問題ないと思います。

個人的には、パワーポイントやExcelなどで描いたドキュメントは非常に保守コストが高いです。慣れて無くて使うの下手な人は一定数いますし、センスが無いと言って触ろうとしない人も多いです。メンテしてくれていても、オブジェクトのポイントが付いていなかったり、なぞにグループ化したりしてなかったり、開発者それぞれにこだわりがあります。

パワポやExcel用にLinterを作れば?という説もありますが、そこまでやるべきなのか?とも思いますし、そこを努力するのか~、という気もします。

このドキュメントは陳腐化しても良い、という基準をどこかで作れると、あのドキュメントが陳腐化しているよね、という罪悪感がメンバーから無くなりますし、メンバーがリーダーに一々相談することもなくなるのでチームの生産性も多少は向上するでしょう。

まとめ

  • 陳腐化して良い部分とそうでない部分を見極め、費用対効果が高いドキュメントを整備しよう
  • なるべく、楽をできるツールを探し、そのツールの上限までは保守することがオススメ
  • いっそ陳腐化することを許容すると割り切れると、幸せになれる