基本設計書に何を書く?テンプレがない状態から「必要な成果物」を逆算してみた
【要約】テンプレなしから考えた基本設計のポイント
| 検討ステップ | 決めること・成果物 | 詳細設計との境界線 |
|---|---|---|
| 1. システム構成 | システム全体の構造・連携関係 | どのようなシステムか(実装構造までは含めない) |
| 2. 機能・シナリオ | ユースケース・利用者の操作フロー | 画面・API・DB・外部IFへ展開する軸 |
| 3. シーケンス | 処理の流れ・データ・IFの概要 | 詳細な個別仕様は各設計書へリンク |
| 4. 後工程からの逆算 | 詳細設計者が判断できる情報 | 「何を実現するか」=基本 / 「どう実現するか」=詳細 |
はじめに
基本設計書を作ることになったとき、「何を書けばいいのか分からない」ってなった経験はないだろうか。
設計書のフォーマットって現場によりけりだけど、正直、今回のように「テンプレートすら存在しない現場」は自分も初めてだった。
今までは決められたテンプレートがあったから、
基本設計とは何を書くものなのか?
を深く考えたことがなかった。
過去には「これって基本設計に書くの?詳細設計じゃない?」みたいに、レビューの時にどこまで書くべきかで揉めた経験もあったりする。
ところが、テンプレートが一切なくなると本当に話が変わる。
「画面設計は必要そうだけど、APIは?」
「DBはどこまで決める?」
「シーケンス図は必要?」
「機能一覧とユースケース一覧は両方必要?」
「そもそも、基本設計と詳細設計の境界はどこ?」
と、次々に疑問が出てきた。
そこで今回は、基本設計について調べながら、
「詳細設計や実装に進むためには、基本設計で何を決めておけばいいのか」
という視点から、自分なりのテンプレートを考えてみる。
なお、この記事では基本設計のすべてを扱うわけじゃない。
今回は、システム構成と機能をどう整理するかに絞っている。
非機能、セキュリティ、運用設計などは別の記事で整理予定。
そもそも基本設計は何を決めるものなのか
最初に、一般的な情報を調べてみた。
IPAの資料では、外部設計の技術領域として、画面、システム振舞い、データモデル、帳票、バッチ、外部インタフェースなどが整理されている。
つまり、基本設計を考えるとき、
「基本設計書という1冊の資料に何章あるか」
だけを見るのはちょっと違うっぽい。
システムによって必要になる設計領域が違うから。
例えば、画面を持つWebシステムなら画面設計が要る。
一方、画面を持たないバッチ処理なら、画面設計は不要。
外部システムと連携しないなら、外部インタフェース設計も必要ない。
そのため、
「基本設計には必ずこの章を入れる」という絶対的なテンプレートがあるわけではない
と考えた方が自然だった。
ここは今回の設計を考えるうえで重要なポイント。
基本設計に必要なものと「基本設計書に書くもの」は別だった
もう一つ、考えていて気づいたことがある。
基本設計として必要な情報と、1冊の基本設計書に記載する情報は同じではない
ということ。
例えば、基本設計に、
- システム構成
- 機能
- 画面
- シーケンス
- API
- DB
- 外部IF
が必要だったとしても、これをすべて1つの資料に詰め込む必要はない。
むしろ、規模が大きくなると、
基本設計 本紙
├─ システム構成
├─ 機能一覧
├─ 利用シナリオ一覧
└─ 各設計書へのリンク
画面設計書
シーケンス設計書
API設計書
DB設計書
外部IF設計書のように分けた方が管理しやすい。
つまり、今回考えたいのは、
「基本設計書に何を書くか」ではなく、「基本設計として何を決める必要があるか」
の方。
まずシステム全体を把握する
最初に必要だと思ったのが、システム構成。
例えば、
graph TD
利用者 --> Web画面
Web画面 --> API
API --> DB
API --> 外部システムのような全体図。
ここで知りたいのは、個々のクラスやプログラムの構造じゃない。
例えば、
- どのシステムが存在するのか
- どのシステムがどこから利用されるのか
- どのシステムと連携するのか
- データをどこで管理するのか
といったシステム全体の構造。
この段階では「どうプログラムを書くか」ではなく、
「どのようなシステムとして作るのか」
を決めることが目的になる。
「機能」と「ユースケース」って何が違うの?
ここで一つ分からなかったのが、「機能」と「ユースケース」の違い。
例えばユーザー管理という領域があったとする。
ユーザー管理
├─ ユーザー登録
├─ ユーザー検索
├─ ユーザー変更
└─ ユーザー削除この「ユーザー管理」のようなものを機能として整理して、その中で利用者が実際に行う操作をユースケースとして考えると分かりやすかった。
簡単に整理すると、
| 用語 | 考え方 |
|---|---|
| 機能 | システムが提供する能力・分類 |
| ユースケース | 利用者がシステムを使って達成する目的 |
| 利用シナリオ | その目的を達成するための具体的な流れ |
という関係。
例えば、
graph TD
A["機能:ユーザー管理"] --> B["ユースケース:ユーザーを登録する"]
B --> C["利用シナリオ①:登録画面を開く"]
C --> D["利用シナリオ②:ユーザー情報を入力する"]
D --> E["利用シナリオ③:登録する"]
E --> F["利用シナリオ④:登録結果を確認する"]というイメージ。
ただし、ここで重要なのは、
「機能一覧」「ユースケース一覧」という資料を必ず作らなければならない、ということではない。
重要なのは、システム全体で何ができるのかを把握できて、そこから個々の設計へ展開できることだった。
「利用シナリオ」を設計の軸にしてみた
ここからは一般的な説明じゃなく、今回自分なりに考えた方法。
システム構成や機能を整理した後、
利用者はこのシステムで何をしたいのか?
を考えることにした。
例えば、次のようなシナリオ。
ユーザー情報を登録する。
この一つの目的を実現するために何が必要なのかを考えていく。
flowchart TD
A[利用者] --> B[ユーザー登録画面]
B --> C[ユーザー情報を入力]
C --> D[登録ボタンを押す]
D --> E[登録API]
E --> F[DBへ登録]
F --> G[外部システムへ通知]
G --> H[結果を受け取る]
H --> I[登録結果を画面に表示]こうすると、最初から
「API設計書を作らなければ」
と考えるより、
「この処理を成立させるには何が必要なのか」
という視点で設計できる。
【具体例】利用シナリオからシーケンス図へどう展開する?
次に、この利用シナリオをシーケンスとして整理する。
sequenceDiagram
actor 利用者
participant 登録画面
participant 登録API
participant 登録処理
participant DB
participant 外部システム
利用者->>登録画面: 登録操作
登録画面->>登録API: 登録API呼び出し
登録API->>登録処理: 入力チェック
登録処理->>DB: DB登録
DB-->>登録処理: 登録成功
登録処理->>外部システム: 外部API通知
外部システム-->>登録処理: 処理結果
登録処理-->>登録画面: 結果返却
登録画面-->>利用者: 登録完了ここまで整理すると、必要な設計がかなり見えてくる。
例えば、
- 画面には何を入力するのか
- APIには何を渡すのか
- DBには何を保存するのか
- 外部システムには何を送るのか
- 正常時はどうなるのか
- 異常時はどうなるのか
といった情報。
つまり自分の場合は、
利用シナリオ
↓
シーケンス
↓
必要な設計を展開という流れがしっくりきた。
シーケンスから画面・API・DB・外部IFを整理する
例えば、ユーザー登録なら、次のように展開できる。
画面
ユーザー登録画面
・画面の目的
・入力項目
・表示項目
・ボタン・操作
・画面遷移API
ユーザー登録API
・入力
・出力
・処理概要
・呼び出し先
・エラー概要DB
ユーザー
・ユーザーID
・ユーザー名
・メールアドレス
・所属ID
・登録日時
・更新日時さらに、
- PK
- FK
- テーブル間の関係
- データの制約
などを整理する。
外部IF
外部ユーザー管理システム
・連携契機
・連携方式
・送信データ
・受信データ
・エラー時の扱いこんな感じ。
こうすると、
「API設計」「DB設計」「外部IF設計」を最初から独立した作業として考える
のではなく、
「ユーザー登録というシナリオを成立させるには何が必要か」
というところから、それぞれの設計に展開できる。
シーケンスに全部書く必要はない
ここで一つ注意したいのが、シーケンス図にすべての情報を詰め込まないこと。
例えばシーケンスには、
登録API
↓
DB登録
↓
外部APIという処理の流れを書いて、
詳細なAPI仕様はAPI設計書、
DBの詳細はDB設計書、
外部IFの詳細は外部IF設計書、
というように分ければよいと思っている。
つまり、
シーケンス
│
├─ API設計書
├─ DB設計書
└─ 外部IF設計書という関係。
そのため、シーケンス設計では、
- 入力
- 出力
- データ項目
- 外部IF
- エラー処理の概要
などを把握できれば、詳細な仕様は個別の設計書へリンクする、という構成にできる。
基本設計と詳細設計の境界はどこなのか
ここは最初かなり曖昧だったし、過去の現場でも「どこまで基本設計に書くべきか」でレビューの時に揉めたことがあった。
例えば、「ユーザー名」を扱うとする。
基本設計では、
ユーザー名
・必須
・最大50文字
・文字列と決める。
これによって、利用者や詳細設計者は、
「ユーザー名は必須で、50文字まで扱える」
と判断できる。
一方、DBに保存するときに、
VARCHAR2(50 CHAR)
NOT NULLとするのは、DB製品に依存した具体的な定義。
このように、
基本設計では「何を実現するか」を決めて、詳細設計では「それをどう実現するか」を具体化する
と考えると整理しやすかった。
同じことが処理にも当てはまる。
基本設計:
ユーザー登録APIを呼び出して
ユーザー情報を登録する。詳細設計:
graph TD
Controller --> Service
Service --> Repositoryのような具体的なプログラム構造まで落としていく感じ。
SQLの具体的な内容やクラス内部の処理なども、こちら側に寄る。
もちろん、この境界はプロジェクトの設計標準によって変わる。
「ここまでが必ず基本設計」という絶対的な線引きがあるわけじゃない。
基本設計のテンプレートどうするか
ここまで考えた結果、最初から項目を固定するのではなく、次のような階層で考えることにした。
基本設計
│
├─ 1. 全体設計
│ ├─ システム構成
│ └─ 技術方式
│
├─ 2. 機能設計
│ ├─ 機能一覧
│ ├─ 利用シナリオ一覧
│ └─ シーケンス一覧
│
├─ 3. 個別機能の設計
│ ├─ 画面設計
│ ├─ シーケンス設計
│ ├─ API設計
│ ├─ 外部IF設計
│ └─ バッチ設計
│
└─ 4. データ設計
└─ DB設計ただし、これはすべてのシステムに必要なテンプレートではない。
例えば、画面がないシステムなら画面設計は不要。
外部システムと連携しないなら、外部IF設計も不要。
バッチが存在しないなら、バッチ設計も不要。
つまり、
システムに存在する設計対象に応じて、必要な成果物を選択する
という考え方。
「基本設計に何を書くか」より「何を判断できる必要があるか」
今回、一番大きく考え方が変わったのはここだった。
最初は、
基本設計にはどんな章が必要なのか?
と考えていた。
でも考えていくうちに、
詳細設計を作る人が、何を判断できなければならないのか?
と考えた方が整理しやすいことに気づいた。
例えば、
graph LR
A[何を入力する?] --> B[画面設計]
C[何を返す?] --> D[API設計]
E[どのデータを扱う?] --> F[DB設計]
G[どのシステムと連携する?] --> H[外部IF設計]
I[どういう順番で処理する?] --> J[シーケンス設計]となる。
つまり、設計書の名前を先に決めるのではなく、
graph TD
A[詳細設計・実装に進むために\n何を判断する必要がある?]
A --> B[その判断に必要な情報は?]
B --> C[どういう成果物で表現する?]という順番で考えていく。
今回の結論
今回、基本設計のテンプレートを考えてみて、最初に考えていた、
「基本設計には絶対にこの項目が必要」
という考え方は変わった。
基本設計には、システム構成、画面、システム振舞い、データ、外部IF、バッチなど、さまざまな設計領域がある。
ただ、それらをすべて1冊にまとめる必要があるわけでもない。
また、すべてのシステムで同じ成果物が必要なわけでもない。
自分の場合は、
graph TD
A[システム構成] --> B[機能]
B --> C[利用シナリオ]
C --> D[シーケンス]
D --> E[画面 / API / DB / 外部IF]という流れで考えると、必要な設計項目を整理しやすかった。
特に重要だと感じたのは、
基本設計のテンプレートを先に決めるのではなく、詳細設計・実装に進むために必要な判断事項から、必要な設計成果物を逆算する
という考え方。
「基本設計には何を書くのか」という問いに対して自分なりには、
「そのシステムを実装するために、後工程が判断できるところまで決める」
というのが一番しっくりきた。
今回は扱わなかった設計
今回の記事では、基本設計のすべてを扱っていない。
特に、
- 非機能設計
- セキュリティ設計
- 運用設計
- 監視
- ログ
- バックアップ・リストア
などは、「システム構成と機能をどう設計するか」というテーマから外した。
これらについては、それぞれ「基本設計ではどこまで決めるのか」を改めて整理する必要があると感じている。
参考資料
※ 基本設計・外部設計の呼び方や成果物の分け方は、開発組織や開発プロセスによって異なります。本記事では、特定の方法を唯一の正解として扱わず、設計項目を考えるための一つの方法として整理しています。