ブレずに、爆速に、安全にプロダクトを作る!〜認知負荷を下げて共通認識を確実なものに〜

こんにちは、soe-j と申します。主に新規プロダクト開発に従事し、ここのところフロントエンドに傾倒しております。

アジャイルやスクラムという言葉が一般的になった昨今ですが、 「小さく作って顧客に見せ、フィードバックをもとに進行方向を調整しつつ次に進めていく」というプロセスが私はとても好きです。 これは、ANDPADが顧客からのフィードバックを沢山もらえる環境であるという前提の上成り立ってるので、本当に感謝しています。(これを書いている間にも「〇〇機能が出来たことで××できるようになりました!」という声が届いてとても嬉しいです!)

いただくだけでは申し訳が立たぬ、それを元に ブレずに 爆速 かつ安全に 価値を提供していかなければなりません。そのためには「小さく作る」ということが肝になっていると感じています。

言うのは易し、じゃあやってみせてと思うところですが、そんなもん答えはありません。ほんの一例として、手元のプロダクトをどう開発してるか言語化してみようと思います。

なぜ小さく作るのか

普段は当たり前のように考えていたので、改めて洗い出してみました。

  • 時間的制約
    • 全部作ってたらいつになるかわからん
    • その間にも世の中は動き続けている!
  • 馬力的制約
    • 短期間でそんな大量に作れない
    • エンジニアを大量投入したところで比例して大量に作れるわけではない
  • 認知の限界
    • 大量の要件を詳細まで把握するのは不可能
    • 「ここどうするんだっけ」の応酬、決まらない

「小さく作る」ことで、認識を合わせ、開発を済ませて、顧客に提供、それに対して顧客からのフィードバック、それを元に次に進む、というサイクルが高速になります。これによって、

  • ニーズからブレずに
  • 爆速に価値提供
  • 認識齟齬なく、もれなくテストをして安全に

というベクトルが強くなっていきます。

小さく作らないとどうなるか

例えば、あるサービスにカレンダー機能を追加することとなり、要件として
「チーム全員の予定を作成/閲覧/編集/削除が出来る」
というようなものになったとします。仮に3ヶ月で作れるとしましょう。

一見簡単そうですが、深堀りしてみると細かな仕様が出てくることが多いでしょう。

  • 他人が作った予定を編集/削除 出来てはならない
  • 管理者であればすべての予定を編集/削除できる
  • 一般ユーザーは、他人を予定に追加することは出来ない
  • etc...

この細かな仕様はコードに落とし込む必要があり、分岐が生まれるたびテストケースが膨らんでいきます。 実装してみると気付く考慮すべき仕様もあるでしょう。その都度、エンジニア間、PdM とすり合わせ続け、大きなイメージを最適化しようと努めるでしょう。

確定していない仕様があちこちで転がり、これら全体を掌握して進めることはどんどん難しくなっていきます。認知の限界、認識のズレ、考慮漏れが発生すれば手戻り、バグ、障害へと繋がるかもしれません。共通認識が確実なものになるまでに3ヶ月経ってしまうかもしれません。

もし、3ヶ月かけてリリースできたとしても、世の中に3ヶ月前のニーズはもうないかもしれません

大きなイメージではすべてを掌握できない

小さく作るとどうなるか

もし、この要件を「自分の予定を作成/閲覧」だけに絞れたら.....?

細かな条件が出てきたとしても、最初の要件に比べればとても少ないものになるでしょう。 小さく作れば要件を確定させることが容易くなり、エンジニア間、PdM の認識ズレも減らせるはずです。

2週間で作れるかもしれません。受け入れテストも数時間で終わるでしょう。 すぐさまユーザーに見せることができて、コアユーザーにいち早く価値を届ける事ができ、フィードバックも得られることでしょう。フィードバックの結果、管理者などという概念が不要だったというオチもあるかもしれません。小さく作っていれば無駄なものを作らずに、次に作るものを軌道修正して進めることが出来ます。

フィードバックを元に軌道修正

小さく作るってどうやるの?

実際、何を意識して、どのように進めているのか、今回は2つの切り口で紹介したいと思います。

  • 要件定義
  • 実装

要件定義

要件定義に関してはプロダクトマネージャー(以下PdM)が神がかっているので、その恩恵を預かっている部分が大きいですw  実際のところはいつかテックブログに....!? と期待を高めながら、日々の PdM とのやりとりでポイントと思った点をあげていきます。

データで判断

小さく作るということは、拾いきれるユースケースを削ることにもなりかねません。 一方、すべてのユースケースを網羅することは無理ゲーです。 このプロダクトを使うコアターゲットを定めて、ある程度ユースケースを絞る必要があります。 とはいえ、絞り方を間違えれば誰も嬉しくないものになってしまいます。 利用ユーザーの実態を捉えること、ひいてはニーズのコアを捉えることが必要不可欠です。

アンドパッドにはデータグループがあり、利用実態を解析するためのデータベースが整備されているため、利用傾向を元に判断することができます。DB設計を始め、ページのレイアウト設計までデータを元に自信を持って決定できます。

バックログが半年先まである

弊チームではPdMが半年先までバックログに要件を並べていて、1つ1つの要件をどこまでの機能とするか、どこまで機能としてあればユースケースを達成できるか、PdMがドキュメント化しています(圧倒的感謝)

すべての要件が煮詰まっているわけではなく、先の方は並んでるだけのものもありますが、直近の1ヶ月分は大体実装検討が進められる精度になっています(いわゆるプロダクトバックログの役割)。 直近1ヶ月分は週次のMTGで PdM が紹介しつつ、エンジニアたちが実装方法に思いを馳せ、大体の実装規模感(要件A, B だったら1週間で終わるかなーくらい)を共通認識にしていきます。もし、溢れそうならその都度調整します。

1ヶ月より先の話でも、要件を固めるのが難しいものはみんなでディスカッションすることもあります。早めにディスカッションすることで、将来あるべき実装が見え、今のうちにリファクタリングすることもできます。他にも「要件Aをやる前に要件Bをやる方が無駄がない」という調整が出来たときは感動さえ覚えました。

ディスカッションの末、要件が細かく分けられることもあります。それらはすぐに着手するものもあれば、他の要件より優先度が低くなるものもあります。言い換えれば、細かく分けなかったら、優先度が低いものを先に作ることになっていたということです。

要件を小さくするポイント

最後に、直近みかけた分解ポイントを列挙しておきます

  • CRUDを限定できないか
    • まずは閲覧だけ作ってリリースするなど
  • 操作者を絞れないか
    • 操作できるユーザーを管理者に限るなど
  • オプションを絞れないか
    • 検索条件、リソースのカラムなど最初から全部必要?

これらのいずれか、または組み合わせで、コアとなるユースケースに沿って小さくなっていきます。

実装

要件が小さくなり、確実な共通認識を持ちながら進められる土壌が整いました。これを無下にする事のないよう、実装も認知負荷をなるべく下げながら安全に開発していきましょう。

要件を分解してプルリクに落としていきましょう。いくら要件が小さくなっているとはいえ、1要件=1プルリクはデカすぎることが多いです。すべて一括で実装できたとして、テストがすべてのパターンを網羅しているかなど抜け目なくレビュー出来る気がしません。

新規画面実装などとなると、全体の実装が大きくなることは予想されます。しかし、そうでないときもプルリクが大きくなるケースがしばしばあります。 そういったプルリクは、大別して「本実装」と「リファクタリング」に分けられると考えています。 今回は、実装を小さく進める方法として、リファクタリングにフォーカスして、よくやる切り口を紹介します。

リファクタリングは別プルリクに

「Aに実装を追加してみたら、Xのインタフェースも変えないとだった。Xのインタフェースを変えるとBも変更しないと....」という数珠繋ぎに遭遇したことはないでしょうか。 これをそのままの流れで実装していくと、気付けば巨大なPRが出来上がります。影響範囲も幅広いでしょう。このとき、脳内では「今回実装する機能」と「いまの改修が影響する機能」と両方考えなくてはならなくなっています。

特に厄介なのが「いまの改修が影響する機能」です。元々どんな挙動をしていたか完璧に覚えている or 完璧なリグレッションテストがあれば問題ないですが、大体そんなものはありません。

リファクタリングだけ切り出して別のプルリクにすることを検討してみてください。一旦「今回実装する機能」を脳メモリから解放できます。余裕のある脳メモリで、リファクタに集中できます。先程は気づかなかった考慮漏れが発見できるかもしれません。

とはいえ心づもりしていても、気付くと手元に大量の diff が生まれていることはしばしばあります。 そんなときは、一度 git commit して別ブランチでリファクタ分だけ切り出したりします。

手間かもしれませんが、一度に複数のことを考えなくて良い恩恵は、レビューアーにももたらされます。レビューアーはレビュー以外の仕事も沢山あるなかで、プルリクを見にきています。1つのことにフォーカスした認知負荷の低いプルリクであれば、サクッとApproveすることも出来るでしょう。

リファクタPRを小さくする

リファクタリングが別プルリクになった時点で、本実装のプルリクは、影響範囲が限定されて、レビューもし易いものになっているはずです。が、そのためのリファクタリングプルリクがデカくなってしまうこともよくあります。

例えば、以下の図はフロント実装の概念図ですが、component1 とそれら周辺(usecase, ApiClient, model など)をリファクタしようとすると component2 のリファクタが必要で、それに伴い component3 の変更が必要で.... というような状況となっています。

こういったときは、図における縦の塊で変更を分割していくイメージで、まずは component2 のリファクタにフォーカスして事を進めます。

そのままやると一気に12コンポーネントを改修するところでしたが、見直して6コンポーネントになりました。 実装者、レビューアーの認知負荷が下がるイメージが伝われば幸いです。

こういった概念図が1つあると状況を整理しやすいので、切り分けに困ったときなど書き出してみることをオススメします。

リファクタリング大事

今回リファクタリングにフォーカスしたのは、リファクタリングこそバグ頻出ポイント だと思っているからです。新規機能実装であれば、全員変更された認識を強く持っているし、受け入れテストも入念にされるでしょう。一方、動作が変わらないリファクタリングは、知らなければ気づかないものであり、知っていても「変わらないこと」を保証するのはとても難しいものです。リグレッションテストで検知できるものもありますが、すり抜けるものも多いのが現実です。プルリクを分割したり段階を踏むことを強く推奨します。

バグ頻出ポイントではありますが、機能実装をする上でリファクタリングは必要なものと考えています。 「リファクタリングなしで機能実装すれば考えることが少ない」と思いきや、どの機能を実装するにも考慮せねばならんスーパークラスが生まれたりします。読み解くことに脳リソースを多く費やすこととなっては「考えることが少ない」とは言えないでしょう。

まとめ

  • 認知負荷を下げて共通認識を確実なものにしよう!
  • 要件を小さく出来ないか、PdMとエンジニアで常に考える
  • データがあると自信を持って小さくできる
  • 要件が未来に向けて並んでいることで、あるべき設計や無駄のない開発を検討することが出来る!
  • リファクタリングは必須!バグ頻出なのでプルリクを細かく段階的に進めよう
  • 実装も小さく認知負荷も小さく進めれば安全で爆速になっていく

書き終えて改めて、フィードバックを投げかけてくれるお客様、その声を届けてくれるビジネス、データグループ、PdM、共通認識を持てるエンジニアチームに感謝です!

言葉足らずな投稿でしたが、ANDPADに入るまでは言語化できなかった思想です。 「ブレずに爆速で安全に価値を届けること」が求められる環境がそうさせたと思っております。

一緒に「プロダクトを成長させること」「安定して開発すること」を推し進めていきたいと思ったら、ぜひカジュアル面談などお越しください!

engineer.andpad.co.jp