外部設計（基本設計）で行う事

# 導入
こんにちは、るっちです。
今回は外部設計（基本設計）で行う事に関して、備忘録として残そうと思います。

# 外部設計（基本設計）
　外部設計の位置づけは、「要件定義で明確になっていない外部仕様を検討する」ことです。
外部設計とは、システムの外部から見たシステムの仕様のことを指し、<INS>システム全体の入力と出力を明確にすることです。</INS>

主なタスクは以下のようなものがあります。
- [ユースケース分析（要件定義で行う事も）](#ユースケース分析)
- [概念モデリング（要件定義で行う事も）](#概念モデリング)
- [非機能要件定義](#非機能要件定義)
- [画面設計](#画面設計)
- [外部システムI/F設計](#外部システムif設計)
- [コマンド/バッチ設計](#コマンドバッチ設計)
- [帳票設計](#帳票設計)
- [データベース論理設計（内部設計で行う事も）](#データベース論理設計)
- [システムインフラ設計と配置設計](#システムインフラ設計と配置設計)

参考:[初めての設計をやり抜くための本](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=115777735917&hvadid=667972755488&hvdev=c&hvqmt=e&hvtargid=kwd-332746090533&hydadcr=4078_13351757&jp-ad-ap=0&keywords=%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&qid=1692097548&sr=8-1)

# ユースケース分析
　ユースケースは、その利害関係者とシステム間でどのようなやり取りが行われていくかを順序に沿った<b>シナリオ</b>で表現します。簡単に「システムの挙動」くらいに考えても良い。
ユースケースには<b>目的</b>があります。その目的を達成する意図があってユースケース記述のシナリオを実行するはずです。シナリオをステップは、<INS>手順を書くというよりも、アクターの意図を書くように心がけましょう。</INS>

　ユースケースとして最低限記述しなければならない内容は、次の4つです。
- ユースケース名
- 主アクター
- 主シナリオ
- 拡張シナリオ

##### ユースケースのサンプルを以下に記載します。

|項目  |記載内容  |
|---|---|
|作成者  |〇〇　〇〇  |
|作成日  |2023年8月3日  |
|ユースケース名  |注文を配送する  |
|主アクター  |配送担当者  |
|事前条件  |注文のステータスが受注済である  |
|主シナリオ  |1.配送担当者は注文の一覧を検索する<br>2.システムは注文日時の古いものから注文を一覧で表示する</br><br>3.配送担当者は古い注文の詳細を表示する</br><br>4.システムは注文の詳細を表示する</br><br>5.配送担当者は注文の商品の配送を支持する</br><br>6.システムは商品の配送指示を配送センターに通知する</br> |
|拡張シナリオ  |なし（エラー時の挙動を記載したりする）  |
|成功時保証  |注文のステータスが配送指示済になる  |
|ビジネスルール  |[ビジネスルール：商品種類ごとの配送センター]参照 <br>（業務を遂行する上での決め事）</br> |

参照先のビジネスルール ↓
|項目  |記載内容  |
|---|---|
|作成者  |〇〇　〇〇  |
|作成日  |2023年8月3日  |
|ビジネスルール名  |商品種類ごとの配送センター  |
|内容  |商品種類によって配送指示に使用する配送センターが異なる。<br>商品種類コードと配送センターコードの対応は以下のとおり。</br><br>家電[IT01] = 配送センター[DS01]</br><br>書籍雑誌[IT02] = 配送センター[DS02]</br><br>CD/DVD[IT03] = 配送センター[DS03]</br>|

#### ユースケースの網羅性
ユースケースの抽出方法はいくつかあります。
|分類  |説明  |
|---|---|
|ユースケース図から<br>抽出する方法  |B2Cのように業務フローが作成できない場Ⓔに、ヒヤリングなどを通してユースケースを中っ出する方法  |
|既存システムから<br>抽出する方法  |既存システムの要件を整理するために、現状ユースケースを作成し、そこから機能を拡張する部分のユースケースを作成する  |
|業務フローから<br>抽出する方法  |企業システムにような業務フローが存在する、もしくは業務フローを作成できるケースで使う方法。UMLのアクティビティ図で記述できる  |

どの方法にせよ、以下の視点で不足がないか確認します。
- 目的を実装するためのユースケースが足りているか
- アクターのライフサイクルからユースケースがたりているか
- 全てのトリガーに対するユースケースが足りているか
- 関係者による承認を得ているか

# 概念モデリング
　ユースケースがシステムの動的な振る舞いを表すものであるのに対して、<b>概念モデルはシステムの静的な構造を表します。</b>会員、注文、配送、返品などのさまざまな概念がどのような意味でどのような関連にあるのかは、ユースケースでは触れていません。概念モデルではその構造を明らかにします。
　システムの構造というとアーキテクチャと同じものと聞こえるが、<INS>アーキテクチャは振る舞いを実装するための構造であるのに対し、概念モデルはデータの構造を表します。</INS>
　概念モデルはUMLのクラス図で記述します。
概念モデルの例 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/275a4637-2870-3d18-3275-ffc7856ee144.png)

概念モデルで表現するものは基本的に以下の3つです。
- 概念の名前を整理する
- 概念の関連を整理する
- 概念の関連の多重度を整理する

#### 概念モデルの書き方
（作成中～）

概念モデルの名前を整理するうえでの注意点は以下の2つです。
- 同じ意味で2つの言葉があれば1つにまとめる
- 違う意味で1つの言葉があれば分割する

例えば、「注文」と「受注」という言葉で、どちらも会員からの注文を表すのであればどちらかにまとめる。
逆に、注文といっても、会員からによるものと卸業者に対してのものがあったとします。これは同じ「注文」でも意味が異なります。したがって、これらは名前を明確に分ける必要があります。

概念の関連を整理するうえでの注意点は、ついつい関連の線をたくさん書いてしまう事です。
会員と商品を直接関連付けたくなりますが、すでに会員と商品は注文と注文明細を経由して関連しています。さらに会員と商品を関連付けると二重で関連付けられることになります。これは冗長すぎる関連です。

概念の関連の多重度を整理するうえでの主な注意点は、1対1の多重度と多対多の多重度です。
多対多の多重度は、「本当にその関連が必要か」「関連の間に新しい概念が存在しないか」に注意する必要があります。

##### 概念モデリング終了の目安
- ユースケース記述に登場する概念がすべて表現されているか
- 画面設計に登場する概念が基本的に表現されているか
- 外部システムI/Fに登場する概念が基本的に表現されているか
- 関係者による承認を得ているか

# 非機能要件定義
　ユースケースや概念モデルで行う機能要件定義に対して、非機能要件を定義することを非機能要件定義と呼びます。機能要件を実現するのがシステムを利用する目的です。<b>非機能要件とは、システム利用者が機能を利用する時に補助的に必要なシステムの品質や性能</b>のことです。非機能要件定義の内容は、負荷テストや運用テストのインプットになる情報です。
　非機能要件は機能要件とは異なり、ユーザー企業からのヒヤリングだけでは導き出せません。システム開発会社が主導して検討する必要があります。
　ISO/IEC9126では、システムの品質特性を以下のように定義しています。
|品質特性  |定義  |
|---|---|
|機能性<br>(functionality)  |指定の条件下でソフトウェアを使用した時、明示的および黙示的ニーズを満たす機能を果たすソフトウェア製品の能力  |
|信頼性<br>(reliability)  |指定された条件下で使用した時、指定のパフォーマンスレベルを維持するソフトウェア製品の能力  |
|使用性<br>(usability)  |指定の条件下で使用した時、ユーザーに理解され、学習され、魅力的なものとなるソフトウェア製品の能力  |
|効率<br>(effuciency)  |指定の条件下で、使用する資源の量に関して適切なパフォーマンスを提供するソフトウェア製品の能力  |
|保守性<br>(maintainability)  |修正に応じられるソフトウェア製品の能力  |
|可搬性<br>(portability)  |ある環境から別の環境に移植可能となるソフトウェア製品の能力  |

（各品質特性の詳細は作成中～）

　機能性のセキュリティに関しては、独立行政法人情報処理推進機構（IPA）が以下のような問題を説明しています。
- SQLインジェクション
- OSコマンドインジェクション
- パス名のパラメーターの未チェック、ディレクトリトラバーサル
- セッション管理の不備
- クロスサイトスクリプティング（XSS）
- クロスサイトリクエストフォージェリ（CSRF）
- HTTPヘッダインジェクション
- メールヘッダインジェクション
- バッファオーバーフロー
- アクセス制御や認証制御の欠落

まずは、こうしたよくあるセキュリティ問題について対応します。そのうえで、システム特有のセキュリティ問題を検討すると良い。

# 画面設計
画面設計では以下のものを作成します。
- UI設計ポリシー
- 画面遷移図
- 画面一覧
- 画面モックアップ
- 画面入力チェック仕様書

画面モックアップは、<INS>実際にHTMLリンクを記述して、画面遷移ができるようにすべきです。</INS>

# 外部システムI/F設計
　外部システムI/Fは、ネットワークやファイル交換などにより、外部システムとデータを交換する部分です。
　一般的に、<INS>外部システムI/Fは、開発するうえでリスクを伴います。できるだけ早く明確な仕様書を入手し、できるだけ早くプロトタイププログラムによる疎通テストを行うと良いです。</INS>
　外部システムI/Fを設計するにあたって、以下のような項目を検討します。
- 接続先
- プロトコル・手段
- タイミング
- インターフェース項目仕様
- 認証・セキュリティ
- 例外処理

　外部システムI/Fは、接続相手先の都合で変更される恐れがあるため、設計するうえでは<b>外部システムI/Fに依存した処理を共通化</b>するべきです。「ネットワークに接続するクラス」「シーケンスを制御するクラス」「受送信データを読み書きするクラス」「例外処理を行うクラス」くらいに共通化して設計する方が良いです。
　また、外部システムI/Fでは、障害発生時などの例外処理をどうするかが重要です。ネットワークやファイル交換によるI/Fでは、データベースのようなトランザクションの仕組みがありません。したがって、例外処理として単に処理を中断してログを記録すればよいのか、それともシステムが自動的に再送するような機能を盛り込むのかなどを検討します。非同期メッセージングサービスのような仕組みを利用して再送を行う場合、障害に関するメッセージなどの順番が大切なものでは順番を管理する必要があります。

# コマンド/バッチ設計
　バッチ設計での主な項目は以下の4点です。
- 実行タイミング
- 実行制御、ジョブ管理
- トランザクション
- リカバリー

　バッチ設計ではパフォーマンスと例外処理が大切になります。
バッチは決められた時間帯の中で大量のデータを処理するので、パフォーマンスを十分に考慮する必要があります。データベース処理は、SQLの記述の仕方でパフォーマンスが大きく異なります。必要であれば、OracleのPL/SQLのような組み込み型のSQLも使うことを検討します。
　データベースを操作するバッチのトランザクションスコープは、パフォーマンスと例外処理に影響があります。トランザクションスコープがあまりにも大きいとなかなかコミットできず、決められた時間に終わらないバッチになってしまいます。逆にトランザクションスコープが小さすぎるとパフォーマンスが悪くなります。

 
# 帳票設計
　各種のレポートや、書面などの帳票の出力を設計します。
帳票ものいくつか種類があります。入力を目的にした帳票や出力を目的にした帳票があります。

# データベース論理設計
　概念モデルをもとにデータベース論理設計を行います。データベース論理設計では、データベースに作成するテーブルとテーブルのカラム、またそれらのテーブルにおけるキーなどを設計します。設計では、<b>論理ER図</b>を作成します。IDEF 1X表記とIE表記のどちらかを用いるのが一般的です。データベース論理設計の目的は、<INS>概念モデルで表現されたモデルをリレーショナルデータベースで扱える形式に書き換えること</INS>です。

#### リレーションの正規化
　正規化とは、データの冗長性を排除し、データに一貫性をもたせて不整合なく管理する方法です。

##### 第1正規形
　<b>繰り返し構造のないテーブル</b>のことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/f62f189b-8351-64b9-d1af-56f36a3c6ed5.png)
このような社員テーブルは学生名に繰り返し構造を持っている（同じ名前の人が複数列現れる）ので、第1正規形ではありません。
例えば、以下のように学生名が田中の人が2回現れる可能性があります。
|学生ID|学生名|コース名|講師|
|---|---|---|---|
|1|田中|数学|鈴木|
|1|田中|物理|藤原|
|2|山本|英語|佐藤|
|3|後藤|数学|鈴木|

　第1正規形にするには受講テーブル新たに作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/2d148772-2c10-93b4-1319-b23ffa3650f4.png)
これにより、
ある学生の名前を変更する場合、すべての行を個別に更新する必要が無くなり、データの不整合性が発生する可能性が低くなります。

##### 第2正規形
　あるテーブルが第1正規形であることに加えて、<b>すべての非キーカラムがすべての候補キーに対して完全関数従属するテーブル</b>のことです。
　<b>候補キー</b>とは、その行を一意に特定することができるカラム、もしくはカラムの集団を指します。候補キーの中から1つが主キーとなります。
　<b>関数従属</b>とは、ある属性Aがきまったら別の属性Bも一意に決定できることです。A→Bと表記します。例えば、コース名→講師という関数従属性があるとき、コース名"数学"が決まれば講師"鈴木"も決まります。
　<b>完全関数従属</b>とは、すべての属性がすべての候補キーに関数従属しているということです。
　そのため、第2正規形は<INS>候補キーの一部だけに関数従属している属性（部分関数従属）を排除</INS>した形といえます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/f7ba4d9b-d55d-f6a7-ead8-1d4ddada25e5.png)
　学生IDとコース名が合わせて主キーである受講テーブルでは、教授の名前はコース名にのみ依存しています。この部分的な関数従属性を排除するために、コースと教授を別のテーブルに分離します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/f809a7d3-36bf-08e9-1b52-e5b255e4849d.png)
これにより、
あるコースの講師を変更する場合、すべての行を個別に更新する必要が無くなり、データの不整合性が発生する可能性が低くなります。

##### 第3正規形
　あるテーブルが第2正規形であることに加えて、<b>すべての非キー属性がいかなる候補キーにも推移的に関数従属していないテーブル</b>のことです。
　<b>推移的な関数従属</b>とは、A→B→Cのような形で、Aが決まればBが決まるが、Bが決まればAに関係なくCが決まるという関係です。そのため、<INS>候補キー以下の属性に関数従属している属性を排除</INS>し、別の表にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/29a5dcda-9ada-7ced-b45f-9c052cc1e280.png)
　コースID→コース名→講師の推移的な関数従属の関係があります。この推移的な関数従属性を排除するために、教授の情報を別のテーブルに分離します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/4753d58d-abee-8fd0-ada9-d76626c83086.png)
これにより、
特定のコースの教授を変更する場合、すべての行で教授の名前を更新する必要が無くなり、データの不整合性が発生する可能性が低くなります。

#### 論理ER図の作成
　概念モデルから論理ER図を作成する際の主な注意点は以下の4つです。
- 主キーを決める
- 関連を外部キーにする
- 多対多の関連を関連テーブルにする
- 継承をリレーショナルで実現する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/6682951e-88c7-29e4-cffe-1d2cfb78562a.png)

# システムインフラ設計と配置設計
　非機能要件定義に内容を踏まえ、システムインフラ設計を行います。<b>システムインフラ設計とは、システムを実現するためにネットワークやハードウェアを構成すること</b>です。インフラ設計で重要な点は、セキュリティ、信頼性、効率（性能、パフォーマンス）です。
　
　システムを開発したら、サーバーマシンなどに配置（デプロイ）する必要があります。<b>システムをどのようにサーバーマシンなどに配置するのかを設計するのが配置設計</b>です。配置設計は開発が始まる前に行う必要があります。配置方法によっては実装方法に影響があるからです。例えば、JavaにはWARやEARといったWebアプリケーションの配置方法があります。
　配置設計を行うには、システムインフラ設計がある程度終わっている必要があります。

# 終わり
以上、外部設計に関する備忘録でした。
他にも備忘録として残しておくと良さような知識を持っていらしたら是非とも共有してほしいです。
次回は内部設計（詳細設計）について残そうと思います。