この記事は、Ubiregi Advent Calendar 2020 の20日目の記事です。
ある開発にあたり、設計レビューをやってみたふりかえりを書こうと思います。
1. 設計レビューをやることにした理由
今年8月後半くらいの時期から、ある外部連携機能の開発がはじまりました。
iOSエンジニア2名、サーバーサイドエンジニア1名(自分)のチームで取り組むことになりました。(その後、サーバーサイドのエンジニアがもう1人参画してくれました)
この開発で、チームを超え参加者を募って設計レビューをやりました。それは、こんな理由からでした。
理由1:BASEさんの設計レビューの記事
ちょうどこの頃、BASEさんの開発チームのブログで、設計レビューについての記事が公開されていたのを読みました。
以下、記事より抜粋します。
サーバサイドの領域を専門にするエンジニアが自分以外にプロジェクト内にはいない・少ない状態になるため、機能の品質が個人に依存しがちな状況になってしまっていた。早い段階で多くの目で見ることで、機能の品質を担保したい。
チームのコードレビューのプロセスは取り入れていたが、コードレビューの段階で指摘を受けると手戻りが大きいので、早い段階で既存のシステムに詳しいチームメンバーによるレビューを取り入れ、手戻りを少なくしたい。
コードレビュー時に初めてコードを渡されても仕様把握が難しいので、チームメンバー側が事前に新機能を把握しておきたい。
コードレビューで設計の根幹に関わる部分の指摘を受けると、すでに実装している部分が無駄になり設計からやり直すことになるため、手戻りが非常に大きくなります。
早い段階でフィードバックを受ければ、心理的にも作業的にも反映させやすく、軌道修正もしやすいと思います。
また、早い段階で複数人の目に触れさせて様々な気づきやフィードバックを受けることで、設計の精度を高めることができそう、と思いました。
理由2:設計を複数人で議論すると作る機能への理解が深まる
この開発に入る前、サーバーサイドのメンバー2、3人でよくペアプロをしていました。
その際、機能の設計について複数人で議論したり一緒に考えながら進めていく場面がありました。
このやり方は、一人で考えて実装しPullRequestを出していくのに比べて、手戻りが少なく、作る機能への理解が深まりそうだ、と感じていました。
理由3:一人で考えるのは危険
今、ユビレジでは、開発対象ごとに小さな複数のチームに分かれて開発をしています。
1チームの人数は2〜5人程度です。内容によっては1人のものもあります。
このような体制のため、自分が属するチーム以外でやっていることはどうしても見えにくくなりがちです。
チーム内に閉じて、バックエンドの設計・実装を一人だけで行うと、自分が知らないドメイン知識や、設計の落とし穴など、見落としが発生しそうだと考えていました。自分の設計力の引き出しにも不安を感じていました。
特に、8月からの開発では、開発終了時期が決まっており、期間が3ヶ月程度と短かったため、スケジュールを守るためにも手戻りや見落としをできるだけ無くしたい、と思っていました。
また、設計を共有していないとコードレビューもしづらくなるのではと思いました。
理由4:一緒に設計を考えたい
一人で考えた設計を「設計レビュー」として複数人でレビューしてもらうよりも、設計を検討する材料を事前に自分で整理しておいて、他のメンバーと議論しながら設計を考える場にした方が、色んな意見を取り込めるのではないか、と思いました。
ユビレジの開発では、「リファインメント」を行うことがあります。
リファインメントとは、直近に行うスプリントの詳細仕様を決めるために行うもので、自分たちが作るものを共有し認識を揃えることを目標とします。これから作る機能の見積もりや、コードや仕様の調査などをして、直近のスプリントでやることを明確にします。場合によっては、仮実装を行うこともあるようです。
「設計レビュー」ではなく、チームを超えて一緒に詳細仕様を考える「リファインメント」をチーム内外のメンバーで行う方が精度の高い設計ができるのでは、と思っていました。
実際、「リファインメント」としてメンバーに参加を呼びかけました。
2. 用意したもの
開催にあたり、以下のものを用意しました。
①開発についての説明資料
開発の背景など必要な前提知識を共有するために、説明資料を用意しました。以下のような内容です。
- この開発でやろうとしていること
- ユーザーストーリーマッピングの記録
- 画面イメージ(アプリのUI案)
- その時点での設計方針(アプリ/バックエンド)
- シーケンス図の叩き台
- 連携先仕様についての調査結果
②データの持ち方のイメージ図
この時点では、データベース設計をER図を起こすまで詳細化はできていませんでしたが、議論の叩き台として、データの持ち方のイメージ図をmiroというオンラインホワイトボードのツールで用意しました。
データベース設計で、関連するテーブルを図で描き、追加するテーブルやカラムなどを書き込み、事前に吹き出しなどで議論したい論点を書き込んでおきました。
miroは、図形どうしを線で繋いだり操作がしやすく、コメントのやりとりもできるため、とても便利でした。
③シーケンス図
処理の流れを整理・共有するために、事前に簡易なシーケンス図を用意しました。
Web Sequence Diagrams というサービスを使いました。
ブラウザ上で、記法に従ってテキストを書いていくと、シーケンス図として描画されていきます。記法も単純でわかりやすいです。(手書き風にもできたりします)
④論点の整理
設計において議論したり意見を聞きたいポイントを、アジェンダに記載しておきました。(6つ程度)
設計案がある場合は、その案と考えられるメリット/デメリットなどを書きました。
また、その論点について、すでにGitHubでIssueを立てている場合はIssueへのリンクを貼りました。
3. いつやったか
開催した時期は、開発のキックオフ後、デザイナーさん、UXチーム、開発メンバーとでユーザーストーリーマッピングを行った後、アプリのUI案を固めていた時期です。
アプリ側はUI案に沿って仮実装も行っていましたが、バックエンド側は現行の仕様や連携先の仕様調査、設計方針の検討をしていた時期で、まだコードを1mmも書いていないタイミングでした。
4. やった内容
3回ミーティングを開催しました。ユビレジは、1日目の記事リモートワークはじめてましたにもあるように、原則フルリモートワークになっているので、すべてビデオ会議でした。
後で議論を見返したいことがあるかもしれなかったので、ビデオ会議は録画しました。(実際に、後で議論した記憶が不明瞭だったときに見返すことがありました)
事前の説明会
開発の背景など必要な前提知識を共有するために、用意した説明資料に沿って、開発でやろうとしていること、その時点での設計内容について説明する会を開きました。
[所要時間: 1時間]
設計レビュー/リファインメント 1回目
いよいよ本番です。
事前に整理した論点に沿って、miroや論点をまとめたアジェンダなどを画面共有しながら、今設計で検討している内容を説明して、意見を伺っていきました。
議論したりフィードバックをもらった内容は、ミーティング後にアジェンダに書き込みました。
[所要時間:1時間半]
設計レビュー/リファインメント 2回目
1回目だけでは議論したいポイントすべてを話せなかったため、1回目から3日程度あけて2回目を開催しました。
1回目のフィードバックを受け見直した内容を、資料やIssueに反映させておきました。
この回で議論したいポイントはすべて話せたので、終了としました。
[所要時間:1時間半]
参加してくれたメンバー
議論した内容はサーバーサイドの設計方針が中心でしたが、サーバーサイドのエンジニアだけでなくiOSエンジニアの方にも参加していただけました。とてもありがたかったです。
回によって人数のばらつきはありましたが、だいたい参加人数は10人(か、それ以上)だったと思います。
5. やってみて
やってみた感想です。
よかったこと
- やろうとしていることを事前にチーム外のメンバに共有できた
- ミーティング後に、GitHubの関連Issueに設計についてのコメントをいただけた
- 自分が考えていなかった設計アイデアが出た
- 認識してなかった、製品についてのドメイン知識を聞くことができた
- 事前に資料をまとめたことで、作る機能についての理解が進む
- 資料を書きながら、気付きがでてくる
- 資料に落とせないものは設計できていないこと、検討できていないこと
- 資料をまとめたので、後から参画する人に説明しやすくなる(その人が理解しやすかったかはまた別の話)
- 資料を書きながら、気付きがでてくる
- ミーティングの内容をテキストで残したことで、なぜその設計にしたかある程度追跡可能になる
- まだ実装してないので、フィードバックを受けて方針変更がしやすい
個人的には、実装に入る前のタイミングで設計レビューをやって本当によかった、やらないと進まなかったと思っています。
自分が考えもしなかった設計アイデアもいただきました。自分一人で考えて実装に入っていたら迷走していたと思います・・。
次に生かしたいこと
かといって、このやり方でよかったのかというと、いろいろ反省点もあります。
特に、リモートでのビデオ会議で、せっかく時間を割いて参加してくれたメンバーの方から意見を引き出せるようなファシリテーションができていたかというとそうではなかったと思います。
開催後のチーム内でのふりかえりで話していたこととして、オープンクエスチョンを全員に向かってすると回答しづらいので、ピンポイントな質問(クローズトクエスチョン)を名指しで聞くと聞かれた方も回答しやすいのではないか、という意見をもらい、なるほどと思いました。
- リモートのビデオ会議で参加メンバーの意見を引き出すのはファシリテーション力や工夫が必要(とてもむずかしい)
- せっかく参加してもらったのに意見を引き出しきれなかったのでは
- 1人でしゃべる時間が長くなってしまった
- 大人数のビデオ会議だと発言のハードルが上がる
- テーマごとに人数を絞ったり部屋を分けても良いかも
- もっと遊び心があってもよかった
- 音楽を流す?
- ホワイトボードでみんな書き込めるような参加型でやってみる?
- 事前説明会は、開発グループに閉じず、UXグループにも声をかければよかった
- 何をつくろうとしているかグループ外にも伝えることができる機会になりそう
6. おわりに
ふりかえってみると、これは設計レビューだったのか、リファインメントだったのか曖昧でした。設計内容を共有し、フィードバックを得て、どう作るかの概要を決めていく場だったと思います。
参加してくれたメンバーが、興味を持ってくれたり、意見を出してくれたり、レビューしようとしてくれたからこそ成り立ちました。本当に感謝でした。
どのレベルの設計でこうしたミーティングをするかについては、概要設計レベルを議論して方針を固めるところまでで良さそう、と思いました。(どんなデータベース設計にするか、どんなモデルが必要か、処理の流れをどうするか etc)
概要の設計方針レベルまではこうしたミーティングで方針を固め共有し、その上でデータベースの詳細なテーブルやカラム定義、アプリとのAPIのやりとりの仕様などの詳細な仕様は、GitHubのIssue上での議論で進めていく、というやり方で十分そうです。
ミーティングの中で聞いた「実装してみないとわからないこともある」という言葉が印象的でした。実際、実装してみてはじめて気づくこともありました。ある程度、設計方針が決まったら、あとは手を動かしていくのが良さそうです。仮実装も良いと思います。
また、今回はこのような形で開催したのですが、開発するものの特性や規模、フェーズによって、合うやり方もかわってくると思います。もっと要件がふわっとしていたり、作るものやUIが明確でない場合は、デザインスタジオをやることもあるようです。
開発した機能は、いずれ、サービスとしてチームを超えて運用していくことになります。 早い段階から、作ろうとしているものをいろんな人の目に触れさせたり、一緒に考えたり、フィードバックの機会を作って共有していくことは良いことだと思いました。