弊社では、これまで様々なシステムを新規開発してきましたが、毎回「スムーズに新規開発するにはどうしたら良いのか」ということを考えます。
「昨日より今日」という目標を持って、この問いに取り組んできましたが、ある程度答えが明確になってきたので、今回アウトプットすることにしました。
新規開発に苦戦している方の一助になれば幸いです。
まずは顧客の「要望」を「要件」に落とし込む
まずは顧客の頭の中にある要望を吸い上げて、要件に落とし込む作業を行います。
「顧客がどのような目的でシステムを作りたいのか」を一人称視点で理解する必要があります。
前提として、顧客と最低限会話できるレベルの業務知識を持っておく必要があります。業務知識といっても概要レベルで構いません。細かな部分は顧客とのヒアリングの中でイメージできれば良いので、ここでは大まかな業務知識を持ち合わせておけば良いです。
業務知識を持ち合わせていないと、顧客が抱えている本質的な課題を捉えることが出来ません。さもなくば顧客から挙げられた具体的な要望を、そのまま要件として捉えてシステムに反映させてしまいます。顧客はシステム開発のプロではないので、要件に矛盾が生じたり、システムとしての一貫性が欠けてしまい、カオスなシステム出来上がってしまいます。
顧客の要望を一人称視点で理解することで、適切な要件に落とし込むことが出来きます。 顧客から挙げられた要望を、グルーピングなどの作業を通じて抽象化を行います。顧客がどのような課題に悩んでいて、どのように改善したいのか。そのためにはどのようなシステムを作ればよいのかを考えていきます。
これらを整理すると、顧客の要望から要件に落とし込む手順を以下の通りになります。
- 顧客と同レベルの業務知識を持ち合わせる
- 顧客の要望をヒアリングする(具体レベルの内容であることが多い)
- 顧客の要望からグルーピングなどの抽象化作業を行い、要件に落とし込む
ワイヤーフレームで顧客と認識を合わせる
要件の成果物としてワイヤーフレームを作成します。 要件に落とし込んだ抽象的な内容をワイヤーフレーム通じて画面という形に具現化します。
実際にワイヤーフレームを作成してみると、抽象的だった要件が段々と具体化されていくことに気付くかと思います。具体化する作業の中で様々な疑問が生じてきます。 それらの疑問を「課題管理表」というシートに全て記載して顧客とのミーティングの中で解決させていきます。
一通り作成すると要件がブラッシュアップされ、より実装イメージが湧いてきます。 ワイヤーフレームを顧客にレビューしてもらい、フィードバックを得るという作業を繰り返すことで、さらにブラッシュアップされていきます。完成物イメージを通じて、顧客と要件の齟齬を無くすことで、相互のイメージ不一致、いわゆる「顧客が本当に必要だったもの」のリスクを潰すことができます。
ワイヤーフレームを作成にはfigmaなどのツールを用いることをおすすめします。 figmaを使うと部品の共通化などが行えるので、顧客のフィードバックを反映するのも比較的容易です。 また、画面遷移の機能も備わっていますので、実物をイメージしてもらいやすいのもメリットの一つです。
洗い出した機能をベースにテーブル設計を行う
ワイヤーフレームが確定すると必要な機能が一通り洗い出されたことになります。この時点でテーブル設計を行います。
テーブル設計の後に画面設計(ワイヤーフレーム作成)を行ったほうが良いという考えもありますが、ワイヤーフレーム=顧客との仕様の確定作業と考えると、テーブル設計を後に回したほうが手戻りが少なくなります。そのため私は画面設計、テーブル設計の順番で進めることを推奨します。
テーブル設計にはdiagrams.net (旧draw.io)の「ソフトウェア > Database3」のプリセットを使ってER図を作成することをおすすめします。diagrams.net使うと各テーブル間の関係線やキーの属性などを直感的に設定できるので、とてもスピーディーにER図を作成することが出来ます。
操作性や非機能要件を元に技術を選定する
ワイヤーフレーム作成を終えると、画面の操作感や複雑性を把握することが出来ます。また、テーブル設計を終えるとシステムの規模感やデータ量が見えてきます。
これらの情報を元に、開発で使用する技術を選定します。言語、フレームワーク、フロントエンド周り、バックエンド周り、ミドルウェア、データベース、その他ソフトウェアなどを決める必要があります。チームのスキルセットやシステムの保守性、非機能要件と照らし合わせて、最適な技術を選定します。
例えば、インタラクティブな画面が多い場合は、SPAベースのフロントエンドを検討します。また、大量データを扱う必要がある場合は、スシャーディングできるデータベースを検討したり、NoSQLの導入なども検討します。
チームのスキルセットも重要な指標です。習熟していない言語や技術を採用するのはリスクを伴いますので、開発難易度とのバランスをみて新たな技術を導入するかどうか判断すると良いでしょう。
粗い粒度でタスク化する
技術選定が終えると、いよいよタスク化できる材料が揃います。
タスク化の粒度は「ログイン機能の作成」「トップ画面の作成」のように機能単位や画面単位のように粗くで構いません。
実際にそのタスクに取り掛かるタイミングで具体的なタスクの細分化を行います。 タスク(親)に対して複数のタスク(子)を持たせる形で細分化を行います。
ZenHub(Githubのプロジェクト管理用アドオン)でいうところの、親タスクをepic、子タスクをissueのような関係です。システム全体の進捗管理は親タスク(epic)で行います。個々の機能単位での進捗管理は子タスク(issue)で行います。こうすることでユーザー目線とエンジニア目線の両方でスケジュール管理ができます。
開発環境、ステージング環境は真っ先に構築する
最も優先度が高いタスクは、開発環境(ローカル)とステージング環境(クラウド)の構築です。
ステージング環境構築は後回しにしがちですが、ローカルとクラウドでは、環境制約によって実装に違いが生じるリスクがあります。 開発環境に依存した実装になってしまい、そのままのコードではステージング環境では動かないという自体になりかねませんので、なるべく早めにステージング環境を構築することをおすすめします。
ひたすらタスクを消化する
ここまで来れば、あとは黙々とタスクを消化していきます。
タスクを消化するフェーズは、その上段にある要件定義、設計、タスク化、環境構築という土壌があって成り立ちます。 土壌がしっかりしていないとタスクはうまく消化できません。
土壌の組み立ては時間がかかる作業ですが、しっかりと思考することで高い保守性が実現できますので、腰を据えて望みましょう。