大規模開発プロジェクトの生産性改善施策

竹下秀則氏:ということで、通常の開発フローについてのスケールを行う準備ができましたが、我々にはもう1つ委譲を検討すべきフローが存在していました。比較的規模が大きい開発プロジェクトについてです。

規模が大きいというのはどういったものか、の定義ですが。弊社ではクライアント、サーバー、フロントエンド、データサイエンティストなどの複数のチームが関わり、プロジェクトマネージャーがアサインされ、キックオフミーティングが開催されるような数ヶ月スパンで進行する案件のことを指します。例えば、新商品開発などがこれに当たります。

こういった大規模プロジェクトのクライアント側のLead役を委譲するために、Component Leadとは別にProject Dev Leadというロールを作りました。

責務としては関係者との窓口の役割やクライアント側の技術的意思決定、そしてスケジュールも含めた両プラットフォームの状況把握などです。Component Leadと比べるとProject Dev Leadはプロジェクトマネージャーの責務の一部も担っているイメージです。

立候補や推薦、指定など、いずれかの方法でDev Leadが決まった後は、先ほども説明したデリゲーションポーカーを使って仕事の委譲度を合意のうえで決定します。

そしてProject Dev Leadの役割として、プロジェクトの進行に合わせて3つのレビューを行ってもらうようにしました。プロジェクトレビュー、テックレビュー、クロージングレビューというものです。それぞれについてご説明します。

1つ目のプロジェクトレビューについてです。これはプロジェクトがキックオフされて詳細設計を開始する前に行います。障害を減らすための試作というのはいろいろと行っているのですが、特に新機能開発時の考慮漏れにより引き起こされる問題の発生を抑えるために、プロジェクトの影響範囲をプロジェクト関係者のみならずチームメンバー全員に共有し、考慮の抜け漏れがないか意見を求めます。

具体的には、Project Dev Leadは、Project Docと呼ばれるドキュメントを作成し、プロジェクトの概要と想定される影響範囲などをまとめます。これをベースにチーム全員で考慮漏れがないかについて議論していきます。

Design Docでレビューの効率化

2つ目のテックレビューについてです。1つ目のプロジェクトレビューでプロジェクトの全体像はみんなが認識できますので、次にiOS、Androidそれぞれのプラットフォームの開発担当者で実装の設計をドキュメントにまとめ、チームメンバーにレビューしてもらいます。これにより実際に開発が始まってからの手戻りを、できる限り減らします。

具体的には、Project Dev Leadは、iOS、Android各プラットフォームの開発LeadメンバーにDesign Docの作成を依頼します。実際にはProject Dev Leadはどちらかのプラットフォームの開発Leadを兼任している場合が多いです。

Design Docが何かについてはここでは簡単に触れるにとどめますが、設計の基本方針を示すドキュメントのことで、テック企業でよく採用されているドキュメントのスタイルです。弊社でも積極的に採用しています。

このステップを踏むことで実装計画に問題がないか、みんなの確認が取れ、開発後に「設計問題がある」という理由で大幅な手戻りが発生することを防げます。また、こうやって事前に整理しておくことでプルリクエストの肥大化を防ぎ、結果レビュアーの負担が減ってレビューの質も向上するのではないか、という期待もあります。

また、iOSとAndroid間でAPIの使い方が異なってしまう問題に関しても、Project Dev Leadがリードして関係者間でコンセンサスを取りつつ、プラットフォーム共通で参照するDesign DocでAPIの使い方について、明確に定義することで対応します。

そして3つ目のクロージングレビューについてです。これは開発が完全に完了し、リリースを終えたタイミングでプロジェクトから離れる前に行います。開発を進行していくと途中で仕様が変わったり、といったことが頻繁に起こります。

それに伴いDesign Docもアップデートされていくものですが、最終的に着地したスペック・実装について共有し、Design Docをアーカイブするのがこのクロージングレビューの目的です。

アーカイブの具体的な方法としては、まずはDesign Docの内容を必要であれば最終的な仕様に合わせて更新します。

そしてDesign Docに書かれている内容のうち、既存仕様が書かれているページにも記載すべき情報をマージします。

さらにそのページのWikiの編集権限を絞り、タイトルに「Archived」と明記するといったものです。こうすることによって、後で検索などでこのページを訪れた方が、一目でドキュメントが開発当時の過去のものであり現在は更新されていない、ということを知ることができます。

最新スペックは基本仕様ページにまとめられている、ということが保証されるので、どのページを信じたらよいか、という混乱がなくせると思います。そして最終的なスペックをメンバーに共有してクロージングレビューは終了です。

ということで、Component LeadとProject Dev Leadという2つの仕組みについてご説明しました。これらによって障害を未然に防ぐ対応、実装の差異への対応、属人化の対応、コードレビューの対応、そしてマネージャーがチーム成長のボトルネックになっている懸念への対応ができました。

参照できるドキュメントを集めたポータルページを用意

次はドキュメントにまつわる課題に対して行った施策をお話しします。ドキュメントがないか、またはあっても古い、という状況をなんとかすることで、オンボーディングの課題やドメイン知識属人化を改善するのが狙いです。

ドキュメントについて整理するにあたり3つのポイントを用意してみました。サーチャビリティ(Searchability)、つまり検索性。クライテリア(Criteria)は基準ですね。そしてメンテナンス(Maintenance)、どう保守・運用していくかです。上からご説明します。

まず検索性についてです。弊社ではWikiにConfluenceを利用しており、当然検索機能で目的のドキュメントを探すことはできるのですが、膨大な数のドキュメントの中から知りたい情報をピンポイントで得るのが難しい、という課題と、関連情報が体系立ててまとまっていない、という課題があります。

そこで必要な情報を作成、または参照する際に、少ない労力でたどり着けるにはどうしたらよいか、という問いを立て、階層構造を定義したポータルページを用意することで対応しました。

各Componentごとの内部仕様に関連するドキュメントを、この階層構造に従って集約していくことにし、参照したい時はまずポータルをひらけばたどり着ける、という状態にすることで、関連情報を含めた情報へのアクセスも容易になりますし、ドキュメントをメンバーが「書きたい」「書く必要がある」と思った時に「場所をどこにしよう」と考えるオーバーヘッドがなくなります。このポータルページをInternal Docsと名付けました。

少し見づらいかもしれませんが、こちらがInternal Docsの構成になります。青い枠が1つのComponentを表しています。Main Docsと書いてある緑の枠が、既存仕様をまとめているドキュメントになります。iOSとAndroid、それぞれのページがあり、それぞれはコモンページをインクルードしています。

また、このMain Docsは各Sub Componentのドキュメント、オレンジの枠ですね、これをインクルードしています。Sub ComponentのドキュメントもiOSとAndroid、それぞれのページがあり、コモンページをインクルードしているという構成です。

スライド右側ですが、赤い枠がDesign Docです。こちらもiOSとAndroid、そしてインクルードされているコモンページという構成で、プロジェクトごとに存在します。水色の枠はMiscドキュメントで、その他の雑多なドキュメントを置く場所としています。

Component Leadの仕組みを考え、ComponentとSub Componentに分解した後、このドキュメントの構成を決めてすぐに左側のMain DocsとSub Component Docsは、全ページを骨組みだけ作成しました。中身はなくてもまずは場所を作ることが大事、と考えたためです。

Design DocはProject Dev Leadのところでもお話ししたように、比較的規模が大きい開発を行う時に担当者が作成し、テックレビューに用います。そして開発が完了した後で行うクロージングレビューの時に、Main DocsやSub Component Docsにマージされ、アーカイブされるという運用です。先ほどもお話ししたように、こうすることで最新の仕様に関する情報はMain Docsに一元化されます。

また、各ページを新しく作成する時のために、Confluenceのテンプレート機能を使って雛形を用意しておくと、ドキュメントを書く人の負担を減らすことができます。

特に今回ご紹介したような、インクルードを前提とした複数ページ構成が1つのセットとなっているような場合、カスタムブループリントという方法で複数ページのテンプレートが用意できるようです。実は私もまだ試せていないので、今後対応していきたいと考えています。3つのポイントの1つ目、検索性について説明しました。

何を基準にドキュメントを作成するか

次に2つ目のクライテリア、何を書くかについてお話しします。ドキュメントを書くということに関しては「コードを読めばわかるから必要ない」という意見を持つ方も多いです。しかし、やはり現実問題、さまざまな前提知識やドメイン知識を事前に持っていたほうが、より負担がなくコードを理解できるでしょう。

また、いざドキュメントを複数人で書く場合、品質やドキュメントの粒度が違うことが問題になるかと思います。なので、ある程度テンプレートを決めて運用したほうがよいと思います。

そして、重要なのは、ドキュメントを書こうとしている対象の機能。これはコンポーネントやモジュールのようなものかもしれません。それを構成するコード群についてのメンタルモデルを、読んだ人が構築できるような情報になっているか、ということです。

メンタルモデルとはその対象に対して人が持つイメージのことで、ここではそのコンポーネントおよびモジュールが、何を目的として・どういった動作を・どのように扱えるか、といったイメージのことを指しています。我々のケースをご紹介します。1つのコンポーネントに対して定義したフォーマットになります。

まずはMain Docsについてですが、こういった項目を書くようにしました。このコンポーネントがどのような機能であるかに始まり、大まかなリリース履歴や用語定義、利用しているリソースファイルなどについての説明、そしてAPIとその利用方法について、データベースデザイン、デバッグ方法などです。

次にSub Componentのドキュメントに書くことですが、こちらは主にダイヤグラムを書くようにしています。特にクラス図と各クラスの説明があれば、大まかな処理の全体像が俯瞰できると思います。その場合でもクラス図は、例えば重要なメソッドだけの記述するなど、必要最小限の情報があればよいと思います。

クラス説明はDoc Commentに書いてあればそれをそのまま持ってくるだけでもよいと思います。とにかく頻繁に書き変わるような実装について書くと、メンテナンスが大変なことになりますので、あくまでも処理の概要をつかむための、それほど簡単に変更が入らないような重要な処理についてのみ記述するようにしたらよいと思います。

3つのポイントの2つ目、内容の基準について説明しました。繰り返しますと、読んだ人が適切なメンタルモデルを構築できるようなドキュメントを目指しましょう、という内容でした。

このような情報が書かれているドキュメントにより、読んだ人全員がその対象コンポーネントやモジュールに対して同じメンタルモデルを作れるようになっていれば、初めて触る部分のコードであったとしても理解の速さと深さのレベルが上がり、その後の成果物であるコードの設計や品質にもよい影響を与え、例えばコードレビューのタイミングでの大きな手戻りなどが減らせるのではないでしょうか。

また、何か仕様を確認したい、といった時も、毎回コードを確認するということをしなくても、このドキュメントを見れば概要をつかめるようになっていると楽ですね。もちろんそれには、ドキュメントが正しい状態を保てていれば、という条件が付くのですが、次はこれについてお話しします。

ドキュメントのメンテナンスはどうするか

ということで、ドキュメントのメンテナンスについてです。まず課題として、簡単に古くなってしまうということと、メンテナンスにコストがかかる、といったことがあると思います。これは永遠の課題と言ってもよいのではないでしょうか。

これについては正直、時間を作ってやるしかない、という身も蓋もない答えになるかなと思いますが、簡単に古くならないような情報を書いていくというのも重要です。

そのためには、クライテリアのところでもお話ししましたように、ドキュメントの内容が詳細に寄りすぎないことが重要だと考えます。実装に関する情報を書く場合は、コードと同じ詳細度の情報を書く必要がないのは言うまでもなく、読者がメンタルモデルを構築できるような必要最低限の情報を記述するようにしましょう。

また、Component Leadのところでもお話ししましたが、ComponentのMain DocsとSub−Component Docsは、それぞれComponent LeadとSub Component Leadが基本的にメンテナンスの責任を持つようにしています。

ふだんの開発中やコードレビューにおいて、ドキュメントの修正が必要そうな変更が発生した場合は、ドキュメントの更新を行います。ですが更新する余裕がない場合などは、チケットを切ってタスクとして登録しておくようにします。

そして定期的にドキュメントのメンテナンスを集中して行う時間を作ります。これをMaintenance Weekと呼び、その時にドキュメントのチェックと、必要であれば更新を行います。また、溜まったチケットがあれば、ここでできる限り対応します。実は我々もまだこれを実際には試せていません。来月初回を開催する予定です。今後半年に1回、1週間ほど時間をかけてできるとよいなと考えています。

ということで、ドキュメントの運用に関する3つのポイントをご紹介しました。まず検索性、これについてはドキュメントの構造を定義し、ポータルページを用意することで、ドキュメントを読みたい人・書きたい人が迷うことなく必要な情報にたどり着ける構造を作りました。

次に基準、何を書くかについてですが、読んだ人がその対象についての適切なメンタルモデルを構築できるような情報にします。また、メンテナンス性を考慮して、詳細に立ち入りすぎない、ということも注意します。

そしてメンテナンスについて。Component LeadとSub Component Leadで既存仕様のドキュメントを管理し、半年に1度ほどの頻度でMaintenance Weekと題して一斉に点検を行う、というアイデアをお話ししました。

生産性を改善した仕組み化あれこれ

さて、長々と説明が続きましたが、以上ですべての課題の対応に道筋ができました。ということで、今日話した内容を振り返りたいと思います。

私はマネージャーとして数年間1つのチームを担当する中で、さまざまな課題に直面しました。それらに対して、今日は大きく分けて3つの取り組んでいる施策についてご紹介しました。

Component Leadシステムでは、どのようにマネージャーからチームメンバーに仕事を委譲していったか。デリゲーションポーカーの活用や、JIRA、GitHub、SlackのTIPSを交えてその仕組みについてもお話ししました。

Project Dev Leadでは、作業の手戻りや障害発生を事前に防ぎ、知識をメンバー間で共有するために行う3つのレビューについて、またDesign Docについても触れました。

ドキュメンテーションでは、検索性向上のために構造を定義したポータルページについて、次にメンタルモデル構築を目的としたドキュメント内容の基準について、そしていかにメンテナンスを行なっていくか。1つのアイデアとしてMaintenance Weekについてお話ししました。

これら施策すべてが密接に絡み合いながら課題を解決する基盤を作ってくれるのではないか、と期待しています。そして今日お話しした内容はまだ運用を始めて3ヶ月ほどなのですが、ドキュメントは確実に増えてきましたし、各Component Leadのメンバーが率先してタスクをハンドリングしてるのも目に入っており、手応えは実感できています。

負荷が減ったマネージャーは次は何をするべきか

また、今後のアクションアイテムもいくつか見えてきています。いくつかご紹介しますと、まずはコードベースをComponentに合わせてモジュール化進行する、というものです。こうすることにより、より各Leadのコード上の責任範囲が明確になりそうです。

次に、ドキュメント記述にもレビュープロセスを設けたほうがよいのではないか、というものです。こちらもあまり負荷がかからない仕組み化ができないかを検討中です。

そして、これは今のところiOSだけになりますが、今年のWWDCでAppleが発表したDocC、ドキュメンテーションコンパイラの機能を使ってドキュメントを構築し、Wikiとどのように共存していくかについても、いろいろと試したいと思っています。

それから分析です。仕組みを運用開始してから実際に各Componentにどのぐらいタスクが発生したのかを分析し、負荷状況によりSub Component Leadの数を増減させるなど、コントロールが必要です。

最終的にこの負荷分散についても、仕組み化できればよいと考えています。今後さらに実運用を重ねた経過についてのお話をまた別の機会でご紹介できればと考えています。

さて、最後にもう1度、キム・スコットさんの言葉を引用します。私が行なった施策によってマネージャーである私の負荷は減り、このキムさんの言葉どおり考える時間を捻出することはできたのでしょうか。

やはりまだ難しいです。なぜなら、私の仕事が減った分、今までよりもよりメンバーのみなさんの活躍を注視し、必要であればヘルプしたり、状況を観察する必要があるからです。でも少なくとももうボトルネックではなくなったと思います。

以上で今回の私の発表を終わります。私たちチームの経験が、みなさんのチーム運用に少しでもお役に立てる部分があれば幸いです。本日はご清聴ありがとうございました。