『システム設計の謎を解く』を読んだまとめ

[『システム設計の謎を解く 強いSEになるための、機能設計/入出力設計の極意』](http://www.amazon.co.jp/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%81%AE%E8%AC%8E%E3%82%92%E8%A7%A3%E3%81%8F-%E5%BC%B7%E3%81%84SE%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%80%81%E6%A9%9F%E8%83%BD%E8%A8%AD%E8%A8%88-%E5%85%A5%E5%87%BA%E5%8A%9B%E8%A8%AD%E8%A8%88%E3%81%AE%E6%A5%B5%E6%84%8F-%E9%AB%98%E5%AE%89-%E5%8E%9A%E6%80%9D/dp/4797358181/ref=tmm_hrd_title_0)を読んだのでまとめ(2014年頃に読み終わってたけどまとめるのを忘れていた)。抜粋になるが、これは良書の部類に入ると思うので設計について深く知りたい人は読んでみる価値があると思う。

# 設計の謎
1. 設計が抱える2つの謎<br />
・設計という分野は範囲が広いゆえに「設計」という言葉の意味がバラバラという謎。<br />
・人、プロジェクト、組織によって設計の範囲が異なり曖昧という謎。<br />
この謎を解決するために、設計という言葉に明確な定義をすることが重要。
2. 工程の設計とシステム構成要素の設計
混乱を招いている一番のポイントは、システムライフサイクルの工程の「設計」とシステム構成要素の「設計」が横並びになっている点である(概念設計、基本設計、運用設計、画面設計、DB設計、プログラム設計、基本設計、インターフェース設計、アーキテクチャ設計、機能設計、詳細設計、外部設計、内部設計、、等の言葉横並びになっている)。これらの用語の意味や範囲を定義し意識を合わせる必要がある。

3. 「よい」設計とはなにか？
・要件を満たしているかどうか(要件とのトレーサビリティ)
・設計要素(データパターンや処理パターン)が網羅的に設計されているかどうか
・同じような設計要素(名称が違うが内容の違いが微妙である要素)が複数存在しないか
・設計要素間で矛盾がないか
・運用を意識した設計になっているか
・わかりやすい構造になっているか
・修正しやすい構造になっているか
・テストしやすい構造になっているか
・再利用しやすい構造になっているか
・拡張しやすい構造になっているか

4. 課題・未決事項を洗い出す
設計をしていると、当然のことながら決定できない、確認しないといけない内容に気付く。例えばデータの持たせ方やデータの単位等、要件として記述されるべき内容が書かれていなかったり等がよくある。そのため、これらを課題・未決事項として洗い出し、整理しながら設計を進めることが重要である。

# 設計へのインプット　~要件定義工程の概要~

設計を行うためには必要な情報が揃ってなければならない。どのような情報が揃っていれば設計できるのか？

1. 業務要件を確認する
・対象業務を確認する(システム化対象の業務が一覧となっている情報を確認する)
・業務の登場人物・役割を確認する
・業務フローを確認し、整理する
・タスク定義を確認する
　※タスクとは、業務フロー内に登場するタスク
・動作場所を確認する
　※動作場所とは、業務が実行される場所。これによってシステム化出来ないケースやネットワークに非接続な場合などを確認する。

2. 機能要件を確認する
業務要件を基にシステムでサポートすべき機能を洗い出したものが機能要件
・機能一覧における機能の粒度を確認する
・機能の事前条件・事後条件を確認する
3. データ要件を確認する
データ要件とは、対象システムが取り扱う情報の種類とライフサイクルを意味している。「情報」の内容は設計で扱うのではないかと思われるが、主たる情報とライフサイクルは設計のインプットとしておくのが良い。
・概念モデルでデータを確認する
・主たるデータのライフサイクルを確認する
4. 外部連携要件を確認する
・外部連携一覧を確認する
・外部連携方式を確認する
5. システムの状態遷移を確認する
システムの状態とは、処理を行う上で区別しなければならないシステムの状態のこと。例えば、「締め処理中」などは代表的なシステムの状態である。
6. 非機能要件を確認する
非機能要件とは機能要件以外の要件(性能、可用性、セキュリティ等)のこと。

# 設計の前にやるべき作業　~共通設計~

1. 全体設計　~システム構成を明確にする~
設計を行う前提条件として、どこまでが範囲内でどこからが範囲外かを意識し、システムの全体像を明確にする必要がある。
・システム境界図を作成する
・システム鳥瞰図を作成する
・サブシステム連携概要を作成する

2. アーキテクチャ方針を作成
設計を行う前提条件として、アーキテクチャ方針および、アーキテクチャ設計のうちアプリケーション設計に影響のある部分を明確にする必要ある。
・オンラインアプリケーション方針
・帳票出力方針
・ジョブ管理・実行方針
3. 標準設計を行い、チーム作業を円滑化
アプリケーション設計を比較的多くの人間(10人以上を想定)で行う場合は、設計文書の書き方などを標準化しておいた方が効率よく作業を進めることができる。
・文書テンプレートを作成し共有
・記述粒度・ガイドラインの策定
・設計標準
4. 共通設計で整合性を高める
設計要素の各設計において、事前に決定しておくことで設計の整合性がよくなり、効率を高められる項目がある。これらの項目について共通でまとめる作業が共通設計である。
・画面共通
・帳票共通
・バッチ共通
・DB共通
・メッセージ共通

# アプリケーション設計としてやるべき作業

1. アプリケーションの複雑さ<br />
・アプリケーションの複雑さを段階的に把握する<br />
・機能の複雑さを段階的に把握する<br />
2. 機能の粒度と、機能間の関係を整理する<br />
・「機能粒度の明確化」が設計の極意<br />
3. 入出力設計のまとめ方<br />
・画面設計　~メニューや遷移、入出力をまとめる~　<br />
・帳票設計　~一覧と明細をまとめる~　<br />
・DB設計　~データの整合性をつねに意識する~　<br />
・外部連携設計　~連携方法と連携先を明確にする~　<br />
4. 処理詳細設計を行う<br />
5. 機能間の整合性を確認する<br />
・DFDでデータとインターフェースの構造を確認<br />
・状態遷移図で状態と機能の関係を確認<br />

# アーキテクチャ設計としてやるべき作業

1. システムアーキテクチャについて<br />
・インフラ設計　~システムの土台となるハードウェア/ミドルウェアー~　<br />
　・サーバ(ハードウェア)<br />
　・ネットワーク<br />
　・ストレージ<br />
　・OS<br />
　・ミドルウェア<br />
3. アプリケーションアーキテクチャについて<br />
・アプリケーションのレイヤー構造<br />
　・MVCモデルのようなアプリケーションのレイヤー構造を決める<br />
・レイヤー間のインターフェースと相互作用を確定させる<br />
・レイヤーのおける実装方針を確定させる<br />
4. アーキテクチャ設計上のポイント<br />
・データ整合性(非機能要件として重要な要素)<br />
　・トランザクション<br />
　・データ更新タイミングとロック<br />
　・マスタ系履歴方針を決める<br />
　・データ削除方針を決める<br />
　・補正トランザクション方針を決める<br />
・セキュリティ<br />
　・認証<br />
　・権限管理<br />
　・セッション管理<br />
　・暗号化<br />
・例外処理の設計<br />
　・例外の種類<br />
　・例外の処理方法<br />
・ログ出力設計<br />
　・ログフォーマット<br />
　・ログの出力先<br />
　・ログの出力タイミング<br />
・メッセージ管理<br />
・性能を実現するためのポイント<br />
　・性能要件における4つの視点<br />
　　・レスポンスタイムによる視点(オンラインアプリケーション)<br />
　　・スループットによる視点(オンラインアプリケーション)<br />
　　・ターンアラウンドタイムによる視点(バッチアプリケーション)<br />
　　・リソース効率<br />
　・性能要件を満たすためのアーキテクチャでの工夫<br />
　　・キャッシュ<br />
　　・リソース追加<br />
　　・分散<br />
　　・見せかけのレスポンスタイムの向上<br />
　・可用性を高めるためのポイント<br />
　　・冗長化による対応<br />
　　・順次更新による対応<br />

# 本書の知識を現場で活用するために

1. 詳細設計工程を理解する<br />
2. アジャイル開発との関係
アジャイルに限らず、基本的にどの開発手法でも設計は行う。そのため開発手法によって設計は不要、、ということはない。