とろろこんぶろぐ

かけだしR&Dフロントエンジニアの小言

保守性の担保のために仕様を整理する方法

はじめに

リリースされたプロダクトをエンハンス開発していく上で、保守性を保ち続けることがとても大事なのは言うまでもありません。 特に複雑な要件は実現するために難解なロジックを書く必要があります。 このことから 要件の複雑さと保守性はトレードオフになりがち です。

保守性を保つ方法はさまざまです。 例えば、可読性を高めるような書き方をした上でコメントを残したり、 Lintやテストなどツールを使ったりなどです。

しかし、この記事では書き方やツールではなく、 そもそも複雑になりそうな仕様を整理し要件から取り外すこと で保守性を保つ取り組みを紹介します。

この記事は Recruit Engineers Advent Calendar 2022 の2日目の記事です。

adventar.org

開発者が仕様の整理に入り込む

フロントエンドエンジニアをやっていると、カジュアルに難解なUI要件が定義された仕様と向き合うことが、 たまによく あります。

プロジェクトやチームによって仕様を決める方法やフェーズ、担当者はそれぞれだと思います。 リクルートでは主に企画職のディレクターが担当して仕様を決めています。 開発職(エンジニア)がディレクターから要件をインプットしてもらい実際に開発を行います。 ディレクターは業務的なドメイン知識は詳しいものの開発の詳しい知識はありません。

仕様は、エンジニアにインプットされる段階では、ビジネス上のさまざまな検討を終えて決定されたものです。 そのためこれまでは基本的には仕様の内容は翻されません。

しかし、実際に仕様の内容をエンジニアが確認すると、開発する上で実現したい要件に対して不要な仕様が混ざっていたり、オーバーキルな仕様が含まれていることがあります。

仕様の是非をきちんと分析して整理し、実装すべきかどうかを見極めることにより、不要なコードが含まれずに品質を担保し続けることができます。

現在、新たな取り組みとして、仕様に対する正式なインプットのタイミングとは別に、要件定義期間で開発レビューをフローに取り入れて、仕様の最適化を図る取り組みを行なっています。

開発者レビューによって取り外すことに至った仕様を3つ紹介します。 *1

例1 直感的仕様

最初の例は、UIに寄った「使い心地」に関する要件です。

取り外した仕様について

内容
背景 対象箇所は検索結果一覧への絞り込み機能のモーダル。絞り込みの条件選択は、カテゴリ(検索軸)ごとに複数の条件を指定して検索できる。条件の数が多いので検索軸ごとにアコーディオンで開閉可能になっている。
課題(目的) なるべく複数の検索軸で条件の絞り込みを行なってもらうために、シームレスに条件を追加させたい。
打ち手(仕様) アコーディオンの中身を下限までスワイプしたら自動的に次のアコーディオンが開く。上限で前のアコーディオンの展開も同様に行う。

なぜ取り外したか

目的に対し適切な打ち手とは言えなかったからです。

考察と取り外しアプローチ

UX 的な仕様は良い悪いが主観的になってしまい判断が難しいです。 特にフロントエンド要件では見た目や使い心地に関わる仕様が多いため、仕様が直感的に陥りがちなケースがあります。 簡単に言うと 「なんとなくこういう動きの方がよさそうだから入れたい」 というやつです。

こういった仕様に対しては2つのアプローチを採ります。

1. なぜ必要なのかをきちんと言語化してもらう

ディレクターに対してなぜこの仕様が必要なのかを言語化してもらいます。 今回の場合は 「複数の検索軸で条件の絞り込みを行なってもらいたいから」 でした。

言語化して気づけることは、「複数の検索軸で条件の絞り込みを行なってもらいたい」に対する打ち手は、 スワイプ案の他にもある ということです。 例えば、よく組み合わせられる条件をユーザーに提示してあげたり、条件ごとに検索結果の件数を表示するという手もあるかもしれません。

本来はそれらを横並びにして検討すべきですが、その考察はディレクター側ではまだ できていない 状況でした。 このことをきちんと説明し理解してもらうことで、本当に「スワイプでアコーディオンが開く」が適切な打ち手なのか再検討してもらうきっかけになります。

2. 実際にプロトタイプを触ってもらう

もう一つは、実際に触ってもらい動作を確認してもらうことです。 想像している使い心地が本当に得られるか、 プロトタイプ的に簡単に作って触ってもらいます

イメージと同じかそうではないかを判断してもらうことができますし、 開発側は実際に作り込んだ場合の難しさを推測しやすくなります。

フロントエンドは HTML, CSS, JS をシュッと書けば CodeSandbox とか CodePen とかで試しに動きだけ作るようなことがやりやすいという特徴があります。 場合によっては Chrome ブラウザの DevTools から本番の画面に対して直接 CSS を書き換えて、 こういうことですか? と尋ねることもできますね。

--

今回の例でも、 1. のようなすり合わせを行った上で、2. で実際に開発したものを触ってもらいました。 その結果、ディレクターは 「思っていたより使い心地が良くない」 とわかり、他の方法と比較検討した上で、今回は仕様装着を見送りました。

今回のように実装装着前に仕様を外すことができれば、不要なコードを含めることなく保守性の担保につながりますし、プロダクトとしても最適な形に近づけることができます。

例2 網羅的仕様

取り外した仕様

次の例は例外的な処理仕様についてです。

内容
背景 複数のユーザーが同時に同じイベントデータを編集/削除することがありうるシステム。
課題(目的) ユーザAが一覧画面を表示している時に、同じタイミングでユーザBが編集画面でデータを削除したら、ユーザAは一覧画面から詳細なデータを閲覧するためにリンクをクリックすると 404 ページになってしまう。
打ち手(仕様) ユーザAが一覧画面を表示している間にリンク先の要素が削除されていたら、ユーザAがリンクをクリックして遷移しようとしたタイミングでデータが削除されている旨をスナックバーで通知する。

なぜ取り外したか

実際にどの程度発生しうる問題か調査したところ、イベントを削除することが多くても数ヶ月に一度発生するかどうかであり、実際には ほとんどありえないケース であることが発覚したためです。

考察と取り外しアプローチ

仕様だけ聞くと確かに、ユーザAの知らぬところでデータの変更があったら知りたい、というのは納得できそうです。 しかし、本当に必要なのかどうかはこの仕様の内容だけでは分かりません。

こういったケースは、例外処理系の仕様にありがちです。 これに対してはなぜ必要なのかを言語化してもらうと同時に、 開発工数が費用対効果に見合うのか を検討してもらうアプローチを採ります。

簡単に言うと、 「どのくらいそういう状況が起きるのか?」 ということです。

仕様を検討するディレクター側としては、あらゆるユースケースに全て対応させる仕様を網羅的に検討しがちです。 例えば、登録や変更のときに通知を出すなら削除の場合も出さなければ... といったことです。

今回のケースでは、上述した通り ほとんどありえないケース だったことが発覚し、仕様は取り外しとなりました。 この機能を作る開発工数を使って、別の機能を作った方がよっぽど効率的と分かりました。

例3 ウォーターフォール的仕様

取り外した仕様

最後の例はリデザインです。

内容
背景 カレンダー形式でイベント情報を表示するUI。次の月に進んだり前の月に戻ったりできる。これはリデザインのため既存で使われている機能のため、利用されるユースケースが多分にあることがわかっている。
課題(目的) カレンダーの月移動を、既存にあるようなボタンによる遷移ではなく、より便利に遷移させたい。
打ち手(仕様) 横スワイプでカレンダーの月を変更する。

なぜ取り外したか

リデザインの 初回リリースには載せない という判断を選択しました。

考察と取り外しアプローチ

リデザインという文脈上、ディレクターやデザイナーの意思としてより良いUI/UXを取り込みたいという意図は尊重できます。

今回のようなケースでは、なぜ必要かを言語化してもらうと同時に、 リデザインした初回のリリースで含めるべき MUST の要件なのか? を検討してもらいます。

実は、開発としては、リデザイン=画面全ての要素を作り直すことになります。 さらにこのリデザインのタイミングで、既存の描画ロジックを再度書き直しを行なっていたり、コンポーネントの再整理などまで行っていたりします。

つまり たとえ同じ機能のままでもコードとしては大規模な修正が入っている ということです。

これは悪いことではありません。

このリデザインのタイミングでコードの品質水準を高く上げるとともに、コンポーネントやロジックの整理とテストの拡充が行われることで、初回リリース後の エンハンス開発のスピードを大幅に上げる ことが想定されています。

要するに、まず初回リリースではMVP版をきれいな形で素早くリリースできれば、一度にドカンと混ぜなくてもその後必要な機能を必要に応じて高速にエンハンスで開発していけば良い、ということです。

先の要件に話を戻すと、カレンダーUIをスワイプで切り替えるためには、切り替えたタイミングで前後の月の情報を再取得して画面を再描画する必要があります。

次の月になるのは、スワイプをどのくらい行った時点で行うのでしょうか?ローディングはどう出すか?WebではスワイプでブラウザバックになるがUXとして問題はないか?日毎の予定を表示する画面ではスワイプで遷移できないため統一性はなくてもよいか? など、検証と実装で1日、2日で終わるようなものとは思えません。

この議論と検討を重ねた上で、リデザインの初期リリースと同時に実施するのは得策ではないと判断して、一時的に仕様を取り下げてもらう決断 をしてもらいました。

ディレクターには、今後のエンハンス計画を依頼しています。 後回しとするために取り外した仕様はこれだけではないため、それぞれの WANT 機能に対して優先度と検証工数、それに対する費用対効果を洗い出し、整理することをお願いしています。

おわりに

プロダクトの保守性を保つアプローチとして、 "開発者が仕様の整理に入り込むこと" を紹介しました。 具体例として、3つの注意すべき仕様の具体例を紹介しました。

全ての話に共通するのは、 仕様の「なぜ」を深掘りし言語化すること です。 追加される仕様が「なぜ」必要なのかをきちんと言語化してもらうことで、ディレクターにとっても要件の意図を再整理でき、エンジニアにとっても納得感を持って開発に臨むことができます。

そして忘れてはいけないもう一つの大事なこととして、 仕様の正解はユーザーが持っている ということです。

取り外した仕様が「本当に取り外してよかったのか?」はユーザーのみぞ知ることを忘れてはいけません。 取り外した仕様は、今すぐにでも必要な機能だったのかもしれません。そうしたらエンハンスで次の月にでも素早くリリースする必要があります。 このために、Google Analytics のログや、ユーザーヒアリング、ファネル分析などを緻密に行って、ユーザーが求める機能を追い求め続けることが大切です。

こういった取り組みを続けていくことで、良いプロダクトに成長していけることを信じて日々取り組んでいます。

*1:どのプロダクトの事象かの情報は伏せており、仕様や要件、各種やりとりが実際とは多少異なっていることをご了承ください。