【まとめ】『はじめての設計をやり抜くための本』から設計フェーズの流れを学ぶ

# はじめに
この記事では、『はじめての設計をやり抜くための本 第2版』（吉原庄三郎/著）から、外部設計・内部設計でやるべきことの概要のみ抜き出してまとめています。
本書の中では、各設計フェーズのより詳細な内容も記されていますが、主題から少し外れるため、今回は扱っていません。
本の内容をより詳しく知りたい方は[こちら](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E8%A8%AD%E8%A8%88%E3%82%92%E3%82%84%E3%82%8A%E6%8A%9C%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E6%9C%AC-%E7%AC%AC2%E7%89%88-%E6%A6%82%E5%BF%B5%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%8B%E3%82%89%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%80%81%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E8%A8%AD%E8%A8%88%E3%80%81%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA%E3%81%BE%E3%81%A7-%E5%90%89%E5%8E%9F-%E5%BA%84%E4%B8%89%E9%83%8E-ebook/dp/B09T2NSJS7/ref=sr_1_1?adgrpid=136951615159&gclid=CjwKCAjwv4SaBhBPEiwA9YzZvBn5mEDWqbF8DTPnuuk96c0_oun44lUz3Ka2mZyPfFOkrvdjSdstzRoCbDIQAvD_BwE&hvadid=618696667640&hvdev=c&hvlocphy=20636&hvnetw=g&hvqmt=e&hvrand=17487806241236179415&hvtargid=kwd-1674903844702&hydadcr=7141_13281480&jp-ad-ap=0&keywords=%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AE%E8%A8%AD%E8%A8%88%E3%82%92%E3%82%84%E3%82%8A%E6%8A%9C%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E6%9C%AC&qid=1665272245&qu=eyJxc2MiOiIxLjMwIiwicXNhIjoiMS4xOCIsInFzcCI6IjEuMDAifQ%3D%3D&sr=8-1)からどうぞ！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/b71c9506-0772-1513-acc0-9e492c0421dd.jpeg" width="300px">

# 目次
- [開発手法](#開発手法)
- [設計の目的](#設計の目的)
- [設計手法](#設計手法)
- 設計の対象
    - 外部設計
        - [ユースケース分析](#ユースケース分析)
        - [概念モデリング](#概念モデリング)
        - [画面設計](#画面設計)
        - [外部システムI/F設計](#外部システムI/F設計)
        - [バッチ設計](#バッチ設計)
        - [帳票設計](#帳票設計)
        - [データベース論理設計](#データベース論理設計)
        - [システムインフラ設計](#システムインフラ設計)
        - [配置設計](#配置設計)
    - 内部設計
        - [画面プログラム設計](#画面プログラム設計)
        - [HTTPセッション設計](#HTTPセッション設計)
        - [ビジネスロジックプログラム設計](#ビジネスロジックプログラム設計)
        - [データベースプログラム設計](#データベースプログラム設計)
        - [データベース物理設計](#データベース物理設計)

# 開発手法
設計フェーズを扱う前に、開発プロジェクトの全体像を確認します。
開発には、以下のような手法があり、その手法によって各フェーズの進め方が異なります。

#### ウォーターフォール型
要件定義→設計→実装→テストを基本的に１回の流れで行います。
上流工程から下流工程にそって開発を進め、各工程が完了してから次の工程に進みます。

#### オブジェクト指向型
イテレーションやスパイラルと呼ばれるサイクルを回すことで開発を進めます。
さらに、オブジェクト指向設計やオブジェクト指向プログラミングを開発に取り入れます。
ex.RUP(Rational Unified Process)

:bulb:イテレーションとは
設計、開発、テスト、改善から構成される開発サイクルの単位。
ウォーターフォール型は全ての開発工程を1つの流れで行うため、開発途中で追加の要望があった場合、工程を大きく戻す可能性があり、納期遅延や追加の費用が発生します。
一方、アジャイル開発などでは開発プロセスを繰り返すことで機能を細かく分けて開発を進めるため、追加の要求に対応しやすくなります。

#### アジャイル型
イテレーションのサイクルを回すことで開発を進めます。
ただし、サイクルが数週間と非常に短く、サイクルを短くするためにコミュニケーションを重視することで設計の重みを大きく減らすことが求められます。
ex.XP(eXtreme Programing)、Scrum、Crystal clear、FDD(Feature Driven Development)

:bulb:イテレーティブ開発
アジャイル型開発のアプローチの1つ。
イテレーションを回し、前回のイテレーションの開発部分も合わせて修正しながら品質を向上させる開発手法です。

:bulb:インクリメンタル開発
アジャイル型開発のアプローチの1つ。
サイクルの度に異なる部分を開発する開発手法であり、スケジュールが立てやすいことが特徴です。
※インクリメンタル開発を主軸とし、イテレーティブ開発の特徴を取り入れると開発がしやすくなります。

# 設計の目的
「開発手法」で開発プロジェクトの全体像を確認しました。
プロジェクトを進めるには、必ず設計フェーズが必要です。では、なぜ設計を行うのでしょうか？
本書では、以下の目的が挙げられています。

①要件定義の内容をシステムでどのように実現するかを検討する
②要件定義で明確になっていない外部仕様を検討する
③開発の関係者間で情報を共有する
④システムの品質を高める
⑤運用後のメンテナンスのために設計情報を残す

:bulb:要件定義とは
開発工数を見積もるために、システムのステークホルダーに対してシステムが必要とする機能や特性を明確に定義する工程。
※この要件定義で定義したことを、実際にどのようにシステムで実現するのかを検討するのが設計フェーズです。

# 設計手法
設計の目的の1つに、「要件定義の内容をシステムでどのように実現するかを検討する」がありました。
システムの設計には以下のような手法があり、本書では現在の主流であるオブジェクト指向設計を基軸にして、設計フェーズについて触れています。

#### 構造化設計
システムを機能で細分化（＝モジュール化）し、システムを機能構造で設計します。
システム間のデータの動きには重きをおかず、機能に重きを置きます。
※構造化設計については[こちら](http://www.sysportcore.com/kota/program/structure.html)のサイトにも詳細が書いてあります。

#### オブジェクト指向設計
オブジェクト指向プログラミングを設計の作業にも応用した手法。
機能とデータのまとまりをオブジェクトとし、システムをオブジェクトの集合として設計します。

# 設計の対象
設計フェーズは、外部設計（＝基本設計）と内部設計（＝詳細設計）とに別れます。

## 外部設計
#### 外部設計とは
システムの具体的な外部使用（システムが利用者や外部システムに対して提供する機能やインターフェイス）を設計し、システム全体の入力と出力を明確にします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/9ecdb357-0885-692a-5e88-b89b5bfc6b0e.jpeg" width=500px>


#### 外部設計の粒度
外部設計は、ユーザー目的レベルで記述します。

:bulb:ユーザー目的レベル
１人の人間が中断なしに行える作業単位。１つの目的（作業）を達成できるレベル。

#### 外部設計で行うこと

##### ユースケース分析
ユースケースとは、システムの利用者（アクター）とシステムとの間に発生するやりとり（商品を検索する、商品をカートに入れる、注文を決済する…など）のことを指します。
ユースケース分析では、やりとりの流れ（＝シナリオ）をユースケースごとに書き出し、システムのユースケースを以下の項目に沿って洗い出します。

　①ユースケース名：ユースケースの名前
　②主アクター：そのユースケースでシステムを利用する特定の利用者
　③主シナリオ：システムの通常利用フロー
　④拡張シナリオ：システムの非常時（エラーなどの失敗時）の利用フロー
　⑤事前条件：ユースケース開始時に保証されている状態
　⑥成功時保証：ユースケース成功時に保証される状態
　⑦最低保証：ユースケース失敗時に保証される状態
　⑧トリガー：ユースケースを実行するイベント
　⑨ビジネスルール：ユースケースが発生する業務上でのルール
　:bulb:ビジネスルールは別ドキュメントにまとめ、ユースケースから参照できるようにしましょう。

<p>図）ユースケース例1</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/3cb7140c-3033-0274-2ce1-78129c5fa3be.jpeg" width=500px>

<p>図）ユースケース例2</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/3c881e3a-0ce1-6582-b472-54dcf33d2fd3.jpeg" width=500px>

上記で挙げた項目を、以下の方法で洗い出します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/f83af2f2-d4ae-291a-0c4e-d31b2b392a03.jpeg" width=500px>

ユースケースを洗い出す際には、以下のことを確認しましょう。
　・目的を実現するためのユースケースが足りているか?
　・アクターのライフサイクルから想定されるユースケースが足りているか?
　・すべてのトリガーに対するユースケースが洗い出せているか?
　・関係者による承認を得ているか?
 
##### 概念モデリング
ユースケースで登場した概念（商品、注文、決済…など）をもとに、システムのデータ構造をUML図で記述します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/da2971ed-104b-748a-0a35-a20a628bff82.jpeg" width=500px>


概念モデリングでは、以下のポイントが重要です。
　①概念の名前を整理する
　　・同じ意味で使われる言葉が複数ある場合、１つに統一する。
　　・違う意味で使われる言葉が重複している場合、言葉を別で定義（分割）する。
　　　例）注文（購入または予約の意味で使われる）→注文と予約に分割する

　②概念の関連を整理する
　　・1対１、多対多の関連に注意する。
　　　例）会員―注文明細―商品　の関連付けがあるのに、さらに会員―商品　の関連付けを行うのはNG

概念モデリングを行う際には、以下のことを確認しましょう。
　・ユースケース記述に登場する概念がすべて表現されているか？
　・画面設計に登場する概念が表現されているか？
　・外部システムI/Fに登場する概念が表現されているか？
　・関係者による承認を得ているか？

##### 画面設計
画面設計では、以下の項目を洗い出します。

①UI設計ポリシー：画面設計時のルールを決める。
　・前提条件
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/0a9ad1a4-baa8-4d74-a40c-c81b5854c588.jpeg" width=500px>
　・画面レイアウトパターン：共通レイアウト（ヘッダー、フッター、メニュー、ボディなど）を設計する。
　・画面機能パターン：画面機能に合わせて画面のボディ構成、レイアウトを設計する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/0f86f2a5-9e4a-2643-8cf2-0b11e10d3836.jpeg" width=500px>
　・画面項目パターン：画面に配置する項目の入出力形式を設計する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/6b0538b5-4c64-4e63-9e3d-ca41a39b0b6b.jpeg" width=500px>
　・画面遷移図：ユースケース実現に必要な画面を洗い出し、その画面同士がどのように関連しているかを図で表現する。
　※作成した画面には、プロジェクトの命名規則に従って画面名と画面IDをつけます。

②画面一覧：画面遷移図に登場した画面を整理し、画面ＩＤを利用して管理します。

③画面モックアップ：具体的な画面イメージをHTMLファイルで作成します。
　画面モックアップには以下の目的があります。
　・画面項目を明らかにする→概念モデルと比較して過不足を確認
　・画面項目の配置を明らかにする
　・画面遷移を確認する
　・実装前の画面イメージを確認する
　・顧客と開発側でシステム設計の確認をしやすくする

④画面入力チェック仕様書：画面モックアップに沿って、画面入力項目の入力チェック仕様をまとめます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/e8046d56-5cee-9b23-93d1-8dd0179ae4d6.jpeg" width=500px>


##### 外部システムI/F設計
外部システムI/F設計では、決済システムなどの外部システムと連携する場合のデータのやりとりを設計します。
洗い出す項目は以下です。
　・接続先
　・プロトコル、手段
　・タイミング
　・インターフェイス項目仕様
　・認証、セキュリティ
　・例外処理

##### バッチ設計
バッチ設計では、以下の項目を洗い出します。
　・実行タイミング
　・実行制御、ジョブ制御
　・トランザクション
　・リカバリー

##### 帳票設計
帳票設計では、各種レポートや書面などの帳票の出力を設計します。
 
##### データベース論理設計
データベース論理設計では、概念モデルを元に、論理ER図を用いてデータベースに作成するテーブルとカラムを設計します。
※本書ではデータベース論理設計についてページを割いて詳しくまとめてあるため、詳細を学習したい方は本書を読むことをお勧めします。
 
##### システムインフラ設計
非機能要件定義の内容を踏まえ、システムを実現するネットワークやハードウェア構成を設計します。
※本書では非機能要件定義について触れていますが、今回は設計フェーズの記事のため割愛します。

:bulb: 非機能要件
機能要件以外の全ての要件を指します。
システムの可用性、性能、保守性、移行性、セキュリティ、エコロジーなどの要件を定義します。

##### 配置設計
インフラ設計を踏まえ、システムをどのようにサーバーマシンなどに配置するのか設計します。


## 内部設計
内部設計では、外部設計を基に、システム内部の動作や機能、物理データなど、ユーザーから見えにくい詳細な部分の設計を行います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/1546188b-a0c2-de52-6360-1b58a829e4b3.jpeg" width=500px>


#### 内部設計で行うこと

##### 画面プログラム設計
外部設計で行った、画面遷移図、画面モックアップ、画面項目定義書をもとに設計します。

■成果物①：Controller一覧
画面遷移図のリンクやフォームからControllerをすべて洗い出し一覧にまとめます。

■成果物②：Controller設計
Controller設計では、UMLシーケンス図（またはアクティビティ図）を用い、次の項目をまとめます。
・リクエストパラメータのバリデーション
・リクエストパラメータの取得
・ビジネスロジックの呼び出し
・レスポンスのデータ設定
・画面遷移

:bulb:UMLシーケンス図
処理の一連の流れをオブジェクト間の相互作用として時系列順に記述します。
オブジェクト間の細かいデータの行き来を記述する際に用います。[参考](https://www.itsenka.com/contents/development/uml/sequence.html)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/78fc2fc6-5911-2491-fd68-e1399fe1d6aa.gif"　width=300px>


:bulb:アクティビティ図
一連の処理の流れと条件分岐を記述します。
内部処理の詳細まで必要なく、簡単に記述するだけの場合に有効です。[参考](https://cacoo.com/ja/blog/what-is-uml/#i-11)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/f63b072a-7b87-0fbf-5106-7e01119fd8a5.png"　 width=600px>


■成果物③：画面共通部分の設計
外部設計のUIポリシー設計で定義した画面レイアウトパターン、画面機能パターン、画面項目パターンから、画面の共通部分を切り出して、各画面から呼び出される共通部品のHTMLファイルを作成します。


##### HTTPセッション設計
「HTTPセッションにどのような情報を格納し、その情報がどこで作成されて、どこで破棄されるか」というセッション情報のライフサイクルを設計します。

:bulb:絵文字HTTPセッション
　HTTPプロトコルにおいて、画面遷移などで状態を保持するための仕組み。
　HTTPリクエストに同じID（＝セッションID）を付与し、リクエスト間に関連を持たせる。
　CookieにセッションIDを付与する方法が一般的。

:bulb:[参考]サードパーティCookie

##### ビジネスロジックプログラム設計
ビジネスロジックプログラム設計では、外部設計で洗い出したユースケースに必要なシステム処理を実現するために、システムに必要なビジネスロジックをどのようにプログラミングするか考えます。

■成果物：ビジネスロジックプログラム設計書
ビジネスロジック（＝ユースケース）のプログラム設計には、主に以下の２つの手法が挙げられます。
参考）『 Patterns Of Enterprise Application Architecture』（マーチン・ファウラー/著）

①TransactionScriptパターン
ビジネスロジックをServiceクラスのメソッドにする手法。
オブジェクト指向と異なり、ドメインの情報がエンティティ（＝データ）とTransactionScript（＝処理）に分散されるのが特徴。
例）OrderService（注文関連のサービス）が、orderメソッド（＝注文ロジック）、cancelOrderメソッド（＝注文キャンセルロジック）等をもつ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/c8347e21-e21f-2a41-337f-45d0ad0fc288.jpeg" width=500px>
②DomeinModelパターン
ビジネスロジックをエンティティに持たせる手法。
オブジェクト指向を踏襲し、データと処理をエンティティにまとめ、カプセル化する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2901907/b0543375-007e-9f81-2974-44513e91759d.jpeg" width=500px>

##### データベースプログラム設計

■成果物①：エンティティクラス図
外部設計で行った概念モデリングをもとに、エンティティのクラス図を作成します。

【クラス図作成の手順】
　①概念モデルの日本語クラス名を英語クラス名にする
　②概念モデルの日本語属性名を英語属性名にする
　③アクセサーメソッドを追加する
　④矢印でクラス間の関連を表現する

■成果物②：DAOクラス図
エンティティに対して１つのDAOを作成します。
DAOは、CRUD＋findメソッドで構成し、トランザクション制御を考慮して作成しましょう。

:bulb:DAO
　データベースを操作する仕組みを提供するオブジェクト。

:bulb:DAOとDTOの違い
　よく似ている言葉にDTOがあります。
　DTOとは、データベースに保存するデータを格納するオブジェクトのことです。
　記事投稿時の仕組みに例えると、DTOのarticleデータをDAOのcreateメソッドの引数で渡し、データベースに記事を保存する、というようにそれぞれ働きが異なります。

:bulb:データベースのトランザクションとは
　データベースへの操作をまとまった単位で確定させる仕組み。
　データベース操作が途中でエラーになったとしても、確定させずにロールバックできるため、データベースのデータの整合性を常に保つことが出来る。

##### データベース物理設計
■成果物①：物理ER図
外部設計のデータベース論理設計で作成した論理ER図をもとに、下記の手順で作成します。
　①テーブル名と列名を英語表記にする
　②列の型やサイズを付ける
　③パフォーマンス設計を行う

:bulb:パフォーマンス設計
　開発前にパフォーマンス設計を行うことで、負荷試験後の問題発生に対応しやすくなります。
　パフォーマンスで重要なポイントは次の通りです。
　　・I/Oを減らす
　　・インデックスでデータを見つけやすくする
　　・結合を簡単にできるようにする
　　・処理はまとめて行う

■成果物②：テーブル定義書
データベースの論理ER図と物理ER図をもとに、デーブルごとの詳細な仕様を定義します。

【テーブル仕様定義項目】
　・テーブル名
　・スキーマ名

【カラムの仕様定義項目】
　・論理名
　・物理名
　・データ型
　・長さ（バイト）
　・精度（最大桁数）
　・デフォルト値
　・必須かどうか
　・主キーの有無
　・外部キーの有無
　・インデックス

# 引用
『はじめての設計をやり抜くための本 第2版』（吉原庄三郎/著）