Pythonでのチームアプリ開発に参画するための学習履歴~要件定義について少し考えてみる~

# はじめに

今回は企画に参加するにあたって、企画主様の

[要件定義～システム設計ができる人材になれる記事](https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8)

この記事を参考に要件定義について自分なりに知識を深めて行こうと思います。

# 要件定義とは
→ **納品の際、顧客・開発側双方で合意できる具体的な事前約束**
(顧客の要求に対して、開発側が顧客は何を作れば満足なのかを明らかにする工程)

# 要件定義のプロセス

####1.アイディア（要望）

顧客・ユーザーはシステムや開発に対して明るくない場合がほとんどなので、アイディアの段階をひたすらヒアリングしていく。

####2.要求

アイディアをある程度ヒアリングしたら、今度はそれを開発側のスキルや納期諸々と考慮してアイディアに対してそれを大まかに機能として実現可能なところを提案していく。

####3.要件

1と2で詰めたところを最終的に具体的にシステムとして必ず実装する機能とその実装方法について合意をする

# プロセスの細分化

あくまで大まかな例として自分で以下のような例を考えてみました。
おそらく実際にはこんな緩い感じではないのでしょうが、あくまでプロセスを具体的に確認してみたということでご容赦いただければと思います。

検討以降は実際の業務のプロセスになるので今回は何をやるかだけ元記事の方から項目だけ頂く形で省略しています。
ちなみに技術的に今は無理ですが将来的に私が作りたいと考えているアプリの構想が元になっているので、実現性とか細かいところは今回は考慮しないということでご承知おきください。

## 要望

####1. 顧客の現状の課題(システムやアプリ作成の動機)を明らかにする

ex. 県内の貸しスタジオやフリースペースをいくつか所有しているが利用の状態が芳しく無く、それを改善したい

####2. 課題に対するゴールを明らかにする

ex.　利用率の昨対比30%増

####3. 現状とゴールのギャップ(＝解決すべき課題のリストアップ)

・ 貸しスタジオというビジネスモデルはそれを利用したいという顧客ありきの受け身の商売であり、また顧客においては場所の確保とともに人数の確保がネックになる場合が多い。

・ 既存の利用登録システムが顧客に対して使いやすいものとは言えないこと


## 要求

#### 企画の背景

####1. 課題解決に必要なシステムの概要

・利用登録においてはカレンダーとタイムスケジュールを用意して、現在の予約の状況を各スタジオやフリースペースごとに一目瞭然にする。

・受け身の商売という部分に関しては、マッチング機能や掲示板・SNSの機能を追加して、顧客に対して場所の提供と人員集めの手間の解消を一手に解決する手段を提案する

＊余談

つまり、ここはどういうシステムやサービスがあれば現状とゴールのギャップを解決していけるかということを討議していく場面なのだと私は思っています。
実際、企業様に面談に伺って業務の内容とのお話を聞くに当然開発側としてはシステム面からどうやってギャップ解決を図れるかというアプローチをしていくのだが、近年はそれに加えて実サービス、つまりビジネス面からもアプローチできないといけない時代になっていることが伺えましたし、多分それができないと炎上案件になる確率も上がる(顧客と開発側でゴールにギャップが生まれてしまう)のかなということを感じています。的外れならぜひご指摘ください。

####2. 具体的に実装したい機能一覧

・ カレンダーUIにおける年月日の選択機能

・ 年月日と利用施設を選択したらタイムスケジュールが出現し、その日の予約状況の可視化・及び時間帯を選択して予約できる機能

・ 登録に伴うCRUD機能

・ 選択された時間帯や利用プランにおける利用料金をもとに申請に応じて、最終的な利用料金を算出する機能

・ マッチング機能を利用するための会員登録機能(ソーシャルログイン化)

・ マッチング機能(メンバー募集の掲示板機能などを含む)

……などなど

## 検討：要求の実現性を考える

#### 技術的に開発可能か？
#### 予算はどの程度必要か？
#### 納期はいつ頃になるか？

## 提案：検討した結果を発注者に戻す（開発者タスク）

#### 実装できる機能
#### 請求する金額
#### 納品できる期日

## 要件：双方が合意した決定事項の最終確認（発注者・開発者が協議して決める）

#### システムに実装する機能一覧
＊ 納期、請求額の目安が記載されるケースもある

# 要件定義で決める事項

Why・What・Howで整理する

## Why：システム開発の目的（要望）
#### 現状の課題
#### ゴール（本来あるべき状態）
#### 現状とゴールのギャップ（解決すべき課題）

→ 以上は先述の項目を参照。

## What：どのように課題を解決するのか
####1.システム導入後の業務フローの作成

・ そもそも業務フローとは？

業務全体の流れをフローチャートにして可視化したもの。
社内システムなどの大規模システム開発で用いる。
横軸にシステムを使う部門と業務詳細の欄を用意し、これをレーンとする。
そして、システムのどの機能をどの部門がどの順序で使うのかを各レーンに記載していく。
最後に業務詳細欄に予め順序として振っておいた番号をインデックスとして紐付け、各作業における業務の詳細を記載していく。
あとは、レーンに業務の規定や機能のマニュアルなどをリンクさせれば完成。

ちなみに今回例として設定したのはtoCなサービスであり、かつそこまで大規模なシステムではないので代わりにユースケース図を作成するのが望ましいと感じた。

・ 作るもの
→ 業務フロー図、ユースケース図

####2.機能要件を明らかにする

・ 機能要件とは？

→ 実装する機能に関する要件(=システムに導入するべき機能の一覧)

今回はプロセスの細分化で明らかにした部分をすべて実装するという体で話を勧めます。

####3.非機能要件を明らかにする

・ 非機能要件とは？

→ 処理スピード、セキュリティなどのシステムの主目的以外の性能部分。つまり、実装する機能以外でシステムにとって必要な要件のこと。

例えば、顧客としてはスケジュール検索で当該施設の予約状況を明らかにする機能を実装したい(機能要件)と言われているが、
検索にかかる時間(非機能要件)については要求されていないのでシステムの主目的とは言えない。
よって、開発側が納期と照らし合わせながら自分たちの裁量で以下のカテゴリの部分を如何に顧客に納得してもらえるか考えないと行けない部分なのだと感じました。

##### 非機能要件のグレード

**・可用性**

→ バックアップ体制・障害発生時の回復方法などの要求。如何にそのシステムを利用可能な状態にできるかという観点。

**・性能及び拡張性**

→ ピーク時の負荷や業務量の増加の対応に関する要求。
例えばシステムの利用者が増えた場合やシステムに対して要求される業務量の変化、またはハードの追加などに対して、どれだけ対応できるようにするかという観点。

**・運用及び保守性**

→ システム運用時の稼働率や問題発生時の対応に関する要求。
可用性が利用可能であったシステムがダウンして利用可能じゃなくなった時、その時間をいかに少ないものとするかという観点なのに対して、
こちらはシステムを如何に利用可能な状態に保てるかという観点である。
システムの利用状況の監視や運用マニュアルの作成・拡充、メンテナンスなどが挙げられる。

**・移行性**

→ 作成したシステムを導入、または旧システムからの移行に関する要求。
移行までのスケジュール調整やリハーサル実施などのプランの策定をする。

**・セキュリティ**

→ 利用者の制限や不正アクセスなどのセキュリティに関する要求。
アクセス制限・不正利用者の監視や発見をする機能や顧客側へのセキュリティ教育のマニュアルなどを用意したりする。

**・システム環境**

→システムの設置環境及び消費エネルギーに関する要求。設備に適した機器の選定や、環境負荷を低減させるシステムの構成などを考える。


##### 非機能要件の注意事項

・ 機能要件の検討が完了したあとで行うこと
→ 機能が変わればわかりやすいところでいうと運用・保守の要件も変わってくるので機能が決まらない限り検討が意味をなさない。

・ 提案は開発側から行う
→ 先述の通り顧客はシステムや開発に関する知識に乏しい場合がほとんどであるため。

・ 要件設定の理由をヒアリングする

→ 代替案を提示出来るようにするため。

引用 [機能要件・非機能要件の書き方【サンプル有り](https://pm-rasinban.com/kinou-hikinou)

>注意しなければならないのは、要件の理由をしっかりと聞き、メモをしておくこと。
例）稼働時間を6時〜22時にする理由
・始発で出勤して作業をする人がいるため
・残業終了時間が22時のため
要件の理由をメモしておかないと、顧客が言った要件を採用するしかなく、代替案が提示できない。
また、思いつきで回答する顧客もいるため、理由はしっかり聞いた方がいいだろう。

同記事より再度引用

>非機能要件も要件に応じて必要なコストが変わってくる。
例えば。
①稼働時間が6時〜22時のシステム
②24時間フル稼働のシステム
→当然、②の方がコストが高い。
　・データバックアップ
　・ツール開発の必要性
　・運用保守の負担増加
「品質は良ければ良いほどいい」と考えるのは当然だ。
だが、非機能要件を充実させればさせるほど、コストが高くなることを顧客にも認識してもらい、要件を選定していこう。

つまり、最初に24時間フル稼働のシステムがいいと言われてその理由を聞き出していないと開発としても無駄な開発をしてしまう可能性があり、
それを運用する顧客側にも負担をかけてしまう可能性がある。
だが、検討の際に理由を聞いてそこに確かな必要性が感じられないのであれば、開発側から開発及び実運用上のコストの点から、無駄ない妥協点を探っていくことができる。


## How：具体的な使い勝手と実装方法(基本設計を行う)

大まかに以下の3点に分類される。

####1.画面設計（UI設計）

機能が決まっていれば、あとはその機能をどのように使ってもらうかということを考えないといけない。
そしてそこにはユーザーがサービス・システムを利用しやすくなるようなという観点が欠如してはいけない。
そういう意味でもUI設計はまず最初に行うべきなのだろう。

実際に私がポートフォリオを作った際は機能が動作する最低限度のUIを設計 → 動作テスト → UI清書という段階を踏んだが、実際の現場ではフルスタックではない場合、デザイナーやフロントエンドの担当がいる場合もあるのでその場合はそういった人たちと相談しながらという形になるのだろうか。

・作るもの

→ 画面遷移図


####2.機能設計

引用

> 機能設計は『裏側で実行する処理、必要なデータ』を定めるフェーズだと理解して下さい。
(中略)
こうすると、誰が見てもどんなプログラムを書けばいいのかをイメージ出来ます。
システムを構成するパーツ構成も明確になるので、チーム内での役割分担も簡単になります。

例えば会員登録、例えば予約情報の取得……とシステムにしろアプリにしろDBとのやり取りは絶対に避けられない。
なので、各機能ごとに以下の3点をUIとセットで簡単にまとめておくと実装の時にやることが捗る。

引用

>裏側の処理（機能名と処理内容）
処理に必要なデータ、データの取得元（画面から入力、DBから取得 など）
処理したデータの受渡し先（画面表示、DBへ保存 など）

ここは私が実際にポートフォリオを作ったときにあまり意識をしていなかったところで、これを怠った結果、いざ予約情報のやり取りをしてみたらDBの設計から一度見直してみないといけないようなことになってしまったので、
非常に大切なことだと感じた。

・ 作るもの

→ GUI設計図など



####3.データ設計


引用

> 決めるべき事項は３つです。
データの具体的な中身
データベース設計
データの流れ（データフロー）

設計において1番最後にやるべき項目であり、かつ1番手を抜いてはいけない部分である。
私はこの部分の知識が薄かったために製作の途中からロールバックする羽目になったし、何よりこの部分の設計だけでだいぶ時間を食われてしまった苦い経験があります。
先述の通り、何をやるにしてもDBのとのやり取りありきなので、ここをしっかり決めておかないと結局その後の処理をきちんと実装できない。

まず、データの中身である。
引用元では

>ここで意識すると良いのは、データは大きく分けて４種類ある点です。
この４種類のデータがシステム内でどのように流れていくのか設計します。
プログラムに「入力する」データ（引数）
Web画面からユーザーが入力するデータ
データベースから読み取るデータ
プログラムから「戻ってくる」データ（戻り値）
Web画面に表示させるデータ
データベースに保存するデータ

と書かれている。
蛇足であるが個人的に確認のため言葉を足すと

・ 処理の引数となるべき値

Web画面からユーザーが入力するデータ
(ex. 会員登録フォームの氏名やメールアドレス)

データベースから読み取るデータ
(ex. 施設の予約状況)

上記2つはその値を引数として処理を実行するためのデータということになる。
前者ex. ではそれらの値を引数としてDBに照合をかけログイン判定をする処理を行うし、後者ex.ではDBに検索をかけ返ってきた値を引数としてさらに処理を行うといったことが考えられる。

戻り値となるデータ

Web画面に表示させるデータ
(ex. 自分の予約情報)

データベースに保存するデータ

こういうことになるだろうか。
この4つのデータを意識しながら具体的にデータの中身と型を決めて、正規化を図っていく。

次に、データベースの設計を行う。

> データベース設計において必要なタスクは３つです。
テーブルの役割を「マスター」と「履歴」に分ける
テーブル間の参照関係を整理する
参照関係をER図に書き起こす

テーブルのリレーションはおそらく初めて設計をする際に1番戸惑うところだと思います。実際戸惑いました。
ただ、やはりリレーションがちゃんとできていないと実装の段階で躓くので怠らないようにしましょう。

リレーションに関して親子関係とか引用元でのマスターと履歴とか色々呼び方があるようだが、考えるときにわかりやすいのは参照されるかされないかでまず分類するといいということである。

実際に作ったER図(そもそも設計があまり良くないのですが一応)がこちらなのですが

![ER図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428779/fa1e9563-8be7-9033-49d6-f02282df9ec7.png)

例えばここのユーザーテーブルはご覧の通りユーザーの登録情報が管理されているテーブルとなります、対して予約情報テーブルは予約情報を管理しているテーブルとなります。
なので、例えば「誰の予約情報なのか」という観点からこの両者のテーブルを見ると、予約情報テーブルはuser_idを用いてユーザーテーブルを参照しているという見方ができるのはなんとなくわかると思います。
よって、

・ 親子関係なら

→ 親 ユーザーテーブル
  子 予約情報テーブル

・ マスターと履歴なら

→ マスター ユーザーテーブル
  履歴 予約情報テーブル

・ 参照する、参照されるなら

→ 参照する 予約情報テーブル
  参照される ユーザーテーブル

ということになる。
こういう関係を機能に応じて必要なだけテーブルを作り、定義していく。
改めてになるがシステム・アプリ制作においてここがまずいとすべてが瓦解してしまいます。
なので、もし同じ初学者でこの記事をご覧になってくださっている方がいらっしゃいましたら、ぜひ引用元や書籍等で改めてテーブル設計について確認を取ることをおすすめします。


・ 作るもの 
→ 
ER図(書く前に簡単な図でテーブルの参照関係を図示するのもアリ)
データフロー図(処理図)

# あとがき

以上、参考記事を元に自分なりに改めて要件定義について少し知識を固めてみました。
紛いなりではありますが、一応ポートフォリオを作った際に要件定義はやったのですがこうしてみるとやはりまだまだ意識しないといけないことや、
実際の業務でやるには足りない知識が多くあることを再確認し、自分はまだまだだと感じました。
開発企画で自分が要件定義を主導してやることは絶対にありませんし、そもそもPGにすらなれていない自分ではありますが、エンジニアは要件定義と設計までできて初めてそう名乗ることができるという先人達の教えもありますし、
何より、プロジェクトの一員として携わる以上何も知りませんは通らないので今回改めて確認できてよかったです。

# 参考サイト

[要件定義～システム設計ができる人材になれる記事](https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8)
[簡単に説明できますか？機能要件と非機能要件](https://www.brain-gate.net/content/column/system-program-functional-requirement/)
[【3つのステップで簡単！】業務フローマニュアルの作り方](https://kashika.biz/manual-2/)