要件定義や設計のポイントを整理してみました

要件定義、基本設計、詳細設計の各フェーズで、何を目的に作業するのか、その作業によりどんなメリットがあるのか、設計におけるポイントは何か、といったことを整理するために記事を書きました。

エンジニア1年目の設計初心者が書いたものですので、間違いやご指摘がありましたら教えていただけますと嬉しいです。

## 要件定義

要件定義とは、システムやソフトウェアの開発において、実装すべき機能や満たすべき性能を明確にする作業のことです。

開発対象となる機能の一覧を作成する作業と説明しているものもありました。

### 要件定義の目的

要件定義の目的は、次のようなものかと思います。

* 要求や要件の漏れによる大幅な手戻りを防ぐ
* システムで実現できること・できないことを明確にして関係者間で同意を得る
* 要件を明確にすることで実装やテストをスムーズに進める

### 要件定義のポイント

#### 要求や要件の漏れを防ぐ

要求や要件に漏れがあることが後になってわかると、大幅な手戻りが発生してリリース予定に間に合わなくなるケースもあるようです。

システムやソフトウェアの開発では、すでになんらかのシステムが稼働していて、そこで発生している課題をシステム刷新により解決したい、というケースが多いようです。そのため、**現行の業務フローや現行システムの設計を理解することが漏れを防ぐポイント**といえそうです。

現行の業務フローやシステム設計に関するドキュメントが存在する場合も、メンテナンスが不十分である可能性もあります。やはり、**業務担当者やユーザといった関係者からの聞き取りが重要**といえそうです。要件定義にかけられる時間が限られている、何度も聞き取りに応じる余裕が発注側にない、といったケースも多いらしく、事前に聞き取りの回数や内容を決めておくと良いらしいです。

#### 実現できる・できない要求について合意を得る

クライアントやユーザの要求をすべて実現することは、予算やスケジュールや法規制などの関係で難しいケースが多いようです。

そのため、洗い出した要求のうち、要件とすべき要求を選択する必要があります。このとき、システムで実現できること・できないことについて発注側に理解してもらい、合意を得ることがクレームや手戻りを防ぐためには必要だと思います。

実現させる要求については**どのように実現させるのか**、実現できない要求については**なぜ実現できないのか**を明確にするとトラブルが防げるようです。特に、既存システムを新システムに置き換える場合、ユーザは今ある機能は残って当然と考えるため、実現できない場合は早めに伝える必要がありそうです。

#### 要件を明確にする

要件が曖昧だと、実装やテストのフェーズで手戻りが発生したり、完成したシステムが期待した動作をしないといったトラブルになります。

一般的には、要求の聞き取りは営業担当の部署が行うことが多いようですが、**要件定義から詳細設計までの上流工程は、下流工程の経験が豊富なエンジニアが担当することが望ましい**ようです。要求をどのように実現できるのか、実現するための手段には何があるのか、などをイメージする必要があるからです。

## 基本設計と詳細設計の違い

基本設計と詳細設計の違いは、**基本設計はシステムを外から見たときにどのような動きをするのかを定めるもの**であるのに対し、**詳細設計は基本設計で決定した動きをどうやって実現するのかを定めるもの**という点にあるようです。

* 基本設計：システムを外から見たときにどのような動きをするのか定めるもの（What）
* 詳細設計：基本設計で決定した動きをどうやって実現するか定めたるもの（How）

基本設計のことを外部設計、詳細設計のことを内部設計と呼ぶこともあるようです。

設計について検索したみた印象では、基本設計・詳細設計という呼び名のほうがよく使われているようですが、個人的には、外部設計・内部設計という名前のほうが、外から見たときのシステムの動き、動きを実現するための方法、という意味を表現できているような気がして好きです。基本設計・詳細設計という名前からか、基本設計は大まかな設計、詳細設計は細かい設計、と誤解されることも多いようです。

### それぞれの具体的な成果物は？

システム設計を通じて作成する表や図にはさまざまな種類があります。

* 機能一覧表

* ユースケース図

* アクティビティ図

* シーケンス図

* 状態遷移図

* 画面遷移図

* ER図

* URI設計

* テスト設計

  など

**これらが基本設計に当たるのか、それとも詳細設計に当たるのかは厳密には決まっていない**ようです。現場によって違う、と説明されていました。ちなみに私の職場では、上記の機能一覧表〜ER図までを基本設計、URI設計〜テスト設計を詳細設計と呼んでいました。

### 基本設計はクライアントに見せることを想定して作る

基本設計は、前工程で洗い出した要件を、どのような画面遷移や入出力操作で実現させるのかといったインタフェース部分を決定する作業です。

**基本設計はクライアントと一緒に確認しながら進めることが多いため、クライアントに見られることを想定して作られる**ようです。たしかに、機能一覧やアクティビティ図は、クライアントにこの設計で問題ないか確認しながら作業を進めていたと思います。

一方、**詳細設計はクライアントを意識せずに開発者向けに設計書を作る場合が多い**らしいです。

## 基本設計

基本設計とは、システムを外から見たときにどのような動きをするのかを決定する作業のことで、クライアントに見られることを想定した設計書を作ることが多いようです。具体的にどの設計書が基本設計に当たるのかは定義されていないらしいですが、画面遷移や業務フローなどのインタフェースの仕様を決定する作業のようです。

以下に紹介しているのは、私の職場で基本設定と呼ばれていた成果物の例です。

### 機能一覧表

機能一覧表とは、システム化の対象を明確にするために作成される資料のことだそうです。

機能一覧表の目的には、次のようなものがあるようです。

* 機能を洗い出して**全体のボリュームを把握する**
* **開発や見積もりの範囲を明確にする**
* 機能ごとの**進捗管理に利用する**

プロジェクトの初期段階では、必要な機能の洗い出しを完全に行うのは難しいですが、**機能一覧の作成を先延ばしにすると、全体ボリュームの把握が遅れてトラブルの原因となるため、不完全でも良いので必ず初期段階で機能一覧を作成するのがポイント**のようです。

### ER図

ER図とは、データベース設計に用いられる設計図のことです。

ER図は、Entity Relationship Diagramの略で、次の4つの概念で構成されるようです。

* エンティティ：データのまとまり、テーブルに対応する
* リレーション：エンティティ同士の関係、依存関係を表現する
* アトリビュート：エンティティ内の属性情報、テーブルのカラムに対応する
* カーディナリティ：リレーションの詳細、1対1・1対多・多対多などを表現する

私が経験したプロジェクトでは、次の3つをER図で表現していました。

* 概念モデル図：エンティティ同士の関係を示した図、アトリビュートは省略、特定のDBMSに依存しない
* 論理モデル図：概念モデル図に主キーや外部キーなどのアトリビュートを追加した図、テーブル構造を表現する
* 物理モデル図：特定のDBMSに向けてデータ型やインデックスなどの定義を追加した図、データ量や更新頻度を考慮する

このように概念モデル図・論理モデル図・物理モデル図を区別していましたが、これが一般的な方法なのかはよくわかりません。

ER図の目的には、次のようなものがあるようです。

* **データ同士の関係を一元的に管理する**
* **同じデータが複数箇所に分散していないか確認する**
* **データ変更の影響がどの範囲に出るのか見やすくする**

ER図はなくても良い、という意見もあるようです。

しかし、**テーブルの正規化が楽になった**、**開発中にもっとも参照する設計書はER図だった**、という経験があるので、個人的にはER図は作っておいたほうが良い、と現時点では考えています。

### シーケンス図

シーケンス図とは、システム内のロジックの流れを視覚的に表現したものだそうです。

シーケンス図を作成するメリットとして、次のようなものが紹介されていました。

* ソースコードが読みやすくなる
* シーケンス図を使って仕様変更を伝えやすくなる
* 仕様レビューがしやすくなる
* 担当者以外でも仕様把握がしやすくなる

シーケンス図を事前に作成することで、**行き当たりばったりなコーディングにならず、読みやすいソースコードが出来上がる**ようです。また、ロジックを図示することで、**コーディング担当者以外でも仕様把握が容易になり、仕様レビューや仕様変更などにも役立つ**ようです。

シーケンス図でモデリングする対象には、次のような種類があるという文章を見ました。

* 利用シナリオ
* メソッドのロジック
* サービスのロジック

このようにシーケンス図でモデリングする対象はさまざまですので、作成を依頼された時点でどのレベルのモデリングが必要とされているのかを確認したほうが良さそうだと思いました。

### 状態遷移図

状態遷移図とは、エンティティの状態が遷移する様子を図に表現したものです。ステートマシン図ともいいます。

たとえば投稿記事の状態であれば、下書き、未公開、公開、削除済みなどの状態があるかもしれません。状態遷移図と作成することで、**そのエンティティが取りうる状態の種類や状態遷移の条件を明確にすることができます**。

個人的には、**状態遷移が可能な経路を明確にしたり、状態をどう表現するかを考えるときに役に立つ**と感じています。ユーザであれば、有効なパスワードを所有していれば有効なアカウント、アカウント登録のためのトークンが有効期限内であれば登録待ち、といった具合に、状態の表現方法を考えるときに状態遷移図を使っていました。

### アクティビティ図

アクティビティ図とは、連続する実行の遷移、つまり一連の手続きを表現するための図、と説明されていました。

アクティビティ図を作成するメリットは、**ユーザとシステム間の業務フローが明確になること**だそうです。

私のプロジェクトでは、会員登録の流れなどをアクティビティ図で表現していました。最初に管理者がアカウント登録用URLを発行し、それがユーザにメール送信され、ユーザは有効期限内にURLにアクセスし、任意のパスワードを入力する、といった流れを図示して、「ここでこんなメッセージを表示してほしい」といったフィードバックをもらっていました。

## 詳細設計

詳細設計とは、基本設計で決定したインタフェースの仕様を、システム内部でどうやって実現するかを決定する作業のようです。基本設計はクライアントと一緒に確認しながら進められますが、詳細設計は開発者のための設計である場合が多いようです。

以下に紹介しているのは、私の職場で詳細設定と呼ばれていた成果物の例です。

### URL設計

URL設計とは、各操作におけるURLやHTTPメソッドを決定する作業のことだと思います。

一般的な設計の手順がどうなのかは調べられなかったのですが、URLはユーザに見られる部分なので慎重に設計したほうが良さそうです。一方で、このURLにしなければ動作しない、ということはないので、統一感があれば良いんじゃないか、という意見もあるようです。

私のいたプロジェクトでは次のようなルールでURLを設計していました。

* リソース名は複数形に統一する
* 作成ページはcreate、編集ページはeditと動詞部分を統一する
* データを取得するだけならGET、データの変更を伴う場合はPOST

この他では、有名なWebサービスのURLを参考にしたりしました。プロフィール編集やFAQページのURLは一般的にはどうしているのか、といったことを調べました。

### テスト設計

テスト設計とは、テスト項目を設計することを指すようです。似た言葉にテスト計画というものがあり、こちらはスケジュールや工数などを検討するもので、テスト設計とは区別されるようです。

テスト設計のメリットは、要求されている機能や品質を保証できることだと思います。テスト設計がなくてもテスト実装はできますが、**事前に設計しておくことで、テストケースの漏れを防いだり、要件定義担当者にレビューしてもらったりすることが可能になります**。

テスト設計をする際、自分がよく理解している機能はテストケースが多くなりがちで、意識しないと偏りが出てしまうそうです。**テスト対象を俯瞰して偏りをなくすためにも、テスト設計は有効**かもしれないと思いました。