仕様は変わる、そのためにエンジニアができること

## はじめに
会社や状況によってプランナー、エンジニア、デザイナーの守備範囲が異なる場合があります。
本記事では少人数での開発を想定し、エンジニアの守備範囲からサービスをより良くするためにできることに対して可能な限りアプローチしていきます。

## 仕様は変わる
Webサービスは運営していて日々刻々と姿を変え変化に対応するスピードが求められるものだと認識しています。

そして想定していたとおりに施策がはまってガッツポーズを取ることよりも、予想外の反応が帰ってきたり、良い結果にせよ悪い結果にせよ、想定どおりにいかなかったりすることの方が多いです。

そんなWebサービスにおいて機能開発を行う際に身近に存在しているもの、それが「仕様変更」です。

「仕様変更は発生しない」と思って進めていると、実装の根幹となる部分の変更を余儀なくされたり、想定していた工数で収まらなくなった結果リリースの遅延といった事態を引き起こします。

同じチームとして達成すべきはサービスの品質の向上であり、会社の事業への貢献であり、仕様変更の発生を理由にリリースの遅延を行うことは、自分たちにとってもサービスを利用しているユーザーにとっても不幸せなことであるため、極力避けるべきです。

今回は仕様変更は発生することを前提とした上で変更によるリリースへの影響を最小限に留めるべく日頃気をつけていることをご紹介します。

## 機能の目的を理解にこだわる
日頃気をつけている点と書きましたが、とくに重要視していることは開発を行う**機能が果たすべき目的の理解**につきます。
「**Why Driven** - 常に「なぜか」を思考し、既存を疑い、目的と手段を考えて行動する」ことを心がけています。

なんとなくこういうことがしたいんだろう、などわかった気になって進めず、不明な点があればプランナーと認識の齟齬なく理解できるまで確認します。

読み込んでいる間も「なぜか」を問いかけ続け、目的を果たすための仕様として適切であるかを含めて読み進めます。

今までの経験上最初に目的を理解していない場合、後の工程で下記のような問題が発生する可能性が高まります。

- 開発が完了した時点でプランナーから思っていたものと違う、とフィードバックがあり改修発生
- 伝える情報の優先度が理解できていないため、ユーザーに効果的な訴求ができていない
- 実装後の品質テストで根幹部分の仕様変更による開発工数の増大
- 度重なる仕様変更によりコードが煩雑になりテストが複雑化、品質の低下
- データベースのテーブル設計の複雑化

場合によってはプランナー自身も根拠が弱かったり、理解があいまいなままであったりすると、後々より大きなインパクトの仕様変更が発生する可能性があります。

**「上がってきた仕様の通りに実装すれば良い」**という固定観念は捨てて、目的を果たすには現在の仕様で良いのか、現在の仕様は目的を果たしているのか、落とし穴にハマっていたり、見落としがないか多角的に見ていきます。

機能の果たすべき目的が理解できていると、開発を行っている段階で気になる大小様々な問題について、いちいち全てを確認しないでも、目的を果たすためにはどうしたら良いのかを考えて提案をすることができ、無駄なコミュニケーションコストを削減することができます。



## 具体的な例をふまえて
カードバトル型のソーシャルゲームを例にした場合に、手持ちのカードを預けられる「倉庫」という機能を新しく追加するという対応が発生し、ざっくりと下記の仕様があったとします。

- 1枠につき100枚のカードを収納可能
- 1枠は無料配布、以降はショップからゲーム内通貨にて購入
- 最大6枠まで拡張可能
- 手持ちカードから複数枚選択して預け入れが可能
- 倉庫から複数枚選択して手持ちカードに引き出しが可能
- グルーピングできるように倉庫には1枠毎にユーザーが名前をつけることができる

## 機能そのものに対するWHY
まず始めに考えることは**「本当に倉庫が必要なのか」**です。
なぜ、なんのために倉庫が必要なのか。自問自答しつつ整理して確認し共通認識とします。

> ① カードの所持枠が足りずに冒険、あるいはガチャを行った結果のカードが獲得できていないため

ならばカードの所持枠を増加させることで実現できないか、なぜ倉庫という形を取るのか？

> ② コレクション要素として現在は使っていないカードを保存しておく

現在使っていないカードを手持ちに所持していることでゲームの利便性が損なわれていることが問題なのか？
もしそうならば該当箇所の利便性を向上させることによって回避できるのではないか？

> ③ ユーザーから要望が上がっている

ユーザーからの要望は本当に倉庫を追加することで解消されるのか？
裏に別の問題を抱えていて緩和策として倉庫が有効なだけであって、本当の問題に対する抜本的な解決策としてはもっと良い手段があるのではないか？

必要に応じてユーザーデータを確認しつつ、立てた仮説が正しいものであるか精度を高めていきます。

仮に下記の点から機能開発が必要になったとします。

- リリースから年月が経過したタイトルであったため②の理由により所持できるカードの枚数が圧迫されてしまった
- 所持枠を増やして解決しようとした場合、デッキ編成時に編成可能なカードが大量に表示されることによるデッキ編成のユーザービリティの低下
- 上記問題からユーザーより倉庫機能の要望が届いた


## 要件や必要な情報の過不足の洗い出し
実装する目的が理解できたところで、次に実際の利用シーンのイメージとユースケースを整理していきます。

- 取り出しのアクションについて

倉庫に預けるアクションは目的からもわかるとおりとして、取り出しを行うときはどういう時なのか、実際のユーザーの動きを想像していきます。

実際にイメージしてみると、1枠の最大枚数である100枚預けていた場合に、必要な1枚を選び出して取り出すことが非常に面倒であると想像できます。
例えば、倉庫に預けられたカードに対して、特定の条件(レアリティや種類)での**フィルタリング、ソート機能**が必要なのではないかという気づきが生まれます。

- 倉庫に名前をつける意味

> グルーピングできるように倉庫には1枠毎にユーザーが名前をつけることができる

また、仕様として上記が設定されているということは、同じグループのカードが増えてきた場合に、新しくグループを切り直したい場合や、とりあえずしまっていたカードに対して、追加で枠を購入した際に**倉庫内でのカードの移動機能**が必要なのではないか

- そもそもどこから倉庫機能を利用するのか

ユーザーは突然倉庫画面に来て倉庫に預け入れを行うのだろうか、手持ちがいっぱいになるというトリガーから機能を利用するのであれば、カード一覧画面から倉庫へのリンクが必要なのではないか？

- 複数ある倉庫の中からどこに格納するのか

ユーザーが倉庫に預け入れを行う場合に、そもそも預けようとしているカードの枚数よりも倉庫の枠の空きが無ければ機能を利用することができない。
最大6枠の内どの枠がどれだけ空いているのかは一覧画面にて可視化する必要があるのではないか？

など様々な利用シーンを想定し、必要な機能および不要もしくは別の形で実現したほうが良い機能がないか洗い出します。
洗い出した後はそれぞれの機能別におおまかに工数を算出し(この時点では実際に開発するか決まっていないので詳細には見積もらない)、どこまでの機能を実現するか、それぞれの優先順位と実装可否をプランナーとすりあわせて行きます。

## まとめ
目的や、機能の役割、過不足が高い精度で理解できているとその後の開発の工程では想定外の工数増加やスケジュールの遅延がなく、また細々とした実装しているうちに気づいたことを相談していたら、その度に仕様が追加されて結果工数が収まらなくなる、といったリスクを回避することができます。

機能の理解が備わっているとテーブル設計も迷いなくシンプルに進めることができますし、目的を達成するために必要なデータの蓄積(ログの埋め込み)にも気がまわりPDCAサイクルのCheck部分へのアプローチがしやすくなります。

実装期間と同等、あるいはそれ以上の工数を割いて仕様や目的の理解につとめるケースもありますが、理解しないまま進めることによって

- この機能をリリースした結果何がどうなったんだろう？
- なにがどう良くなれば成功といえるのだろう？
- そもそもなんでリリースしたんだろう？
- どう振り返ればいいんだろう？

などとリリースした後で嘆くことほど虚しいことはないと考えているため、目的を理解することに重点を置いて開発を行っています。