5.1 システム設計の全体像
従来からある、ウォーターフォル型の開発の際に行われる上流工程の例を以下に示します。プロジェクトの規模や対象システムによって多少異なることはありますが、考え方は概ね同じで「概要から詳細」「全体から細部」に向かって設計を行なっていきます。

最初のインプットとなる、システムの目的とステークホルダーのニーズなどを明確化することを要求定義といいます。この要求を分析した結果を元にシステムとして実現すべき事項であるシステム要件(System Requirement)を定義します。
「要求」と「要件」は異なるものです。要求はユーザーがやりたいと思っていることですが、実際には、バジェット、リソース、期間、従うべき法令、環境などの外的な制約や技術的制約があり、やりたいことが全て叶えられるわけではありません。「できること」と「できないこと」をしっかり峻別するのも要件定義の役割です。
やりたいことを実現するための方法を考えるということが「システム設計」をするということです。その中でも一番上位の設計概念が、「システム方式設計」があり、ここではどのような仕組みを使ってシステムを組み立てるかを考えることになります。
間違えやすいのが、要件定義と方式設計の順序です。要件定義の結果を受けて、アーキテクチャ設計を行うのが正しいように見えますが、必ずしもそうではありません。要件定義は、制約条件の中で「実現可能な」システムを定義するものですので、要件が実現できるアーキテクチャは、本来要件定義と並行して行う必要があります。そうでないと、実現可能なかどうか不明なまま要件を決める事になり、実現可能だったとしても、後からコストや工程が大幅に増加してしまうことになりかねません。
その後、基本設計、詳細設計という順に設計内容をモジュールに分割して、細分化、詳細化していきます。「データ設計」もその過程で行いますが、モジュールの分割とはあまり関係ないことが多いため、比較的独立した流れになります。
5.2 要件定義
要件定義書は「システムがユーザに何を提供するか」つまり「何を作るか」を定義するドキュメントです。通常、ユーザーとベンダーが協力して作成を行います。(要求定義書はユーザーが主体で作り、要件定義書はベンダーが主体で作るというケースが多いように思います)
要件定義書に含まれるのは、だいたい以下の内容です。
- 概要
- 業務要件
- 機能要件
- 非機能要件
- 技術要件・稼働環境要件
定義書を書くにあたって、重要なのは「網羅性」です。ここに書かれていない機能は、普通に行けば作られることはありません。必要なものを漏らしてしまうと後で重大な問題になったりします。
以下、要件定義書にはどのような内容を記載するのかの例を見てみます。
(1) 概要
以下のシステムを開発する上での共通認識として持っておくべき事項を記載します。
- システム化の目的
- 現状の課題
- プロジェクトの背景
- 用語の定義
「用語の定義」には、この後の仕様書で使うであろう「そのドメインの専門用語」などを辞書のように記載しておきます。
(2)業務要件
このシステムが使われる業務の要件を記載します。この要件の定義を通じて、システム化を行う範囲を決定していきます。
業務要件一覧
システム化を行う対象業務を抽出し一覧形式で記載します。各業務の説明に加え、「誰が」「どの程度の頻度で」この業務を行うかの情報も記載します。

業務フロー図
業務要件一覧で記載した業務ごとに業務フローを記載します。下に示すのは、システムが導入された後を示す「システム化業務フロー図」ですが、これまで人が行ってきた業務をIT化するなどの場合には、システム導入前の業務の状態(As-Is業務フロー図)を先に記載することもあります。

システム化業務フロー図により、システムが実施する事項と、人間が実施する事項が明確になります。
(3)機能要件
業務要件からシステムが実施する機能を抽出して、これらについての要件を記載します
| 項目 | 記載内容 |
| 機能一覧 | 機能名、機能説明、分類(UI、帳票、バッチなど)、対応業務要件 |
| 画面 | 画面名称、処理概要 ラフデザイン、入出力項目、 対応機能要件 |
| 帳票 | 帳票名称、処理概要、様式(サイズ、印字方向、フォーマット)、出力項目、対応機能要件 |
| バッチ処理 | バッチ処理名、処理概要、事項タイミング、対応機能要件 |
| 外部インタフェース | インタフェース名、接続先、目的、その他(データ形式など)、対応機能要件 |
以下は機能一覧の例です。業務要件で定義したどの要件と対応しているかを「対応業務要件」で紐づけています。

以下は画面定義の例です。業務一覧の分類で「UI」となっているものが、記載されます。機能一覧のどれに対応しているかを「対応機能」に示します。

(4)非機能要件
機能以外の要件をここに記載します。機能以外の要件とは以下のようなものです。
| 項目 | 内容 |
| 性能 | 将来的なユーザー数増加への対応、組織改変への対応 |
| 可用性 | 稼働率、障害発生時の復旧時間、システムメンテナンスの頻度・時間 |
| 拡張性 | 将来的なユーザー数増加への対応、組織改変への対応 |
| 互換性 | 旧システムから引き継ぐデータ、ファイルなど |
| セキュリティー | アクセス制御、認証方式、情報漏洩対策など |
| データ移行 | 旧システムからのデータ移行に必要な作業、移行にかかる時間 |
| 運用・保守 | システムメンテナンスのために必要な作業、マスターデータの変更作業、障害時の対処 |
以下は、記載例です。

特に、可用性についての条件は、システムアーキテクチャに大きく影響するため重要です。
(5)技術要件、稼働環境要件
OS、ブラウザ、サーバー、ミドルウェア、開発言語、フレームワークなどを定義します。
5.3 アーキテクチャ設計
アーキテクチャ設計の目的は、システム全体の高レベルな構造と構成要素の関係を定義し、システム全体の枠組みを提供することです。主な内容は、システムを構成する主要なコンポーネントやサブシステムを定義したり、各コンポーネントがどのように相互作用してデータの流れや通信がどのように行われるかを決定したりすることです。また、アーキテクチャ設計は、システムの設計思想を反映したものになります。
(1)システムアーキテクチャ設計
システムアーキテクチャとは?
システム全体の構造や各サブシステム間の関係をシステムアーキテクチャと呼びます。システムアーキテクチャには、いくつかの代表的なパターンがあります。多くの場合、このうちのどれかを選択するか組み合わせでシステムアーキテクチャが定義できます。
クライアントサーバーアーキテクチャ
サービスを提供する「サーバー」と、サーバーにリクエストを送ることでそのサービスを使う「クライアント」から成るアーキテクチャです。データの処理と管理を処理するサーバー機能を集中化し、クライアントはユーザーと対話しながらサーバーにサービスを要求することで、リソースの効率と管理を改善するように設計されています。
メールシステムやオンラインストレージシステムなど多くのシステムがこのアーキテクチャをとっています。

Web3層アーキテクチャ
「プレゼンテーション層」「アプリケーション層」「データベース層」の3つから成る、システムを機能や責務に基づいて複数の階層(レイヤー)に分割する「多層アーキテクチャ」の一種です。ほとんどのWebシステムがこのアーキテクチャ(または、ここから派生したアーキテクチャ)をとっています。

マイクロサービスアーキテクチャ
Web3層アーキテクチャから派生したアーキテクチャで、アプリケーションを小さな独立したサービスに分割します。
各サービスは独自のデータベースやコードベースを持ち、独立してデプロイでき、スケーラビリティや柔軟性が向上します。AmazonやNetflicsなどの大規模で多様なサービスを提供するサイトのシステムなどで使われています。

イベント駆動型アーキテクチャ
イベントと呼ばれる状態変化をトリガーとして、異なるコンポーネントが非同期で連携します。産業系の監視システムなどでよく使われます。

システムアーキテクチャ設計の実例
「システムアーキテクチャ設計」では、どのような仕組みを使ってシステムを組み立てるかを考えます。基本的なシステムアーキテクチャ(Web3層アーキテクチャなど)を決めた後、「知っておきべき知識」にあった要素を組み合わせて設計を行なっていきます。特にWebシステムでは、すでに世の中にあるパッケージソフトやフレームワークソフトやOSSなどを可能な限り活用することが重要です。自分で制作する部分は極力小さくすることで、
- リリースまでの時間を短くすることができる
- 陳腐化を防ぎ長く使えるシステムとすることができる
- 保守のためのコストを抑えることができる
などのメリットが得られます。
下の図は、アーキテクチャ設計の一例です。このアーキテクチャでのシステム開発を例にとって説明していきます。

緑色はすでにあるソフトウェアを活用する部分、ピンク色は新たに製作する部分を示しています。この例では、プレゼンテーション層の実現にはSPA(シングルページアプリケーション)を採用することにしました。また、ブラウザとサーバ間でのデータのやり取りはREST APIを使うことにします。そのためには、SPAを実現するためのフロントエンドフレームワークが、バックエンドにはREST APIを構築するためのフレームワークが必要になってきます。フロントエンドにはReactとその関連パッケージを使っています。バックエンドはPythonで開発することにし、フレームワークとして、DjangoとDRFを使っています。
Webサーバとデータベースには、それぞれ有名どころのApacheとPostgresqlを採用しています。システムに使うソフトウェアに何を採用するか、開発言語を何にするかは、最近では、選択肢が多いこともあり、結構悩むところです。機能、性能、軽量性、スケーラビリティなどで比較しようにも、ネットに一般的に挙がっているような情報(例えば、「フレームワーク10選」みたいなもの)は、割と定性的、主観的なので、あまりあてになりません。
どれにしたら良いか迷ったら、現時点で「人気がある(シェアが高い)」ものを選択するのが良いのではないかと思います。人気があるものは、それだけ使っている人も多く、学習するための情報が手に入りやすいというメリットがあります。また、今人気があるものは、しばらくは陳腐化しなさそうというのも良い所です。もっとも、開発を通じた技術を使ってエンジニアとしてのキャリアアップを狙っている人の場合は、人気が高いものを選択することが必ずしも正解ではありません。まだ使っている人が少ない技術を身につける方が、より価値が高いエンジニアになれる可能性もあるからです。
(2)システム基盤アーキテクチャ設計
システムを支える基盤技術の構成を設計するものです。サーバー構成、ネットワーク構成、セキュリティ設計、運用設計などが含まれます。
特に、非機能要件によっては、特に可用性を高めたり、システムの負荷を分散するための冗長化構成が必要な場合は、このシステム基盤アーキテクチャ設計で方式を設計します。
よく使われる、冗長化方式を以下に挙げておきます。
アクティブ/スタンバイ(マスター/スレーブ、デュプレックスシステム)
通常時に稼働するアクティブ機(本番機)と、障害発生時に待機するスタンバイ機(予備機)を用意する冗長化構成です。アクティブ機に障害が発生すると、自動的にスタンバイ機に切り替わります。広く使われている方式ですが、アクティブとスタンバイが切り替わる時間がかかるため、故障の際の停止が許容されないシステムなどには向きません。

アクティブ/アクティブ(マルチマスター、デュアルシステム)
用意した同一のシステムを常時稼働させる構成です。すべてのシステムを常に稼働させることで、トラブルがない平常時は処理にかかる負荷が分散されます。どのシステムで処理を実施するかといった定義はなく、処理を行うタイミングで利用するシステムが決定されます。いずれかのシステムに異常が発生した場合には稼働している残りのシステムにて処理を継続することができます。

N+1冗長化
上記2つを組み合わせた構成です。複数(N)のアクティブ機と1台のスタンバイ機を用意し、アクティブ機の1台に障害が発生すると、スタンバイ機がこれに取って代わります。負荷分散と冗長化の両方が必要な場合によく使われます。

5.4 データ設計
データ設計(データモデリング)は、「データを構造的に整理し、ビジュアルなモデルに表現することにより、データを効率的に扱えるようにすること」を意味します。一般的に、その設計の成果はエンティティ、属性、関連(リレーション)を定義したER図として表されます。また、それに付随したデータディクショナリも成果物となます。データベースの設計は、「概念設計」、「論理設計」、「物理設計」の3段階で行われ、より抽象的なモデルから具体的なモデルへと段階を踏んでいきます。
概念設計
実際のデータベースの実装はあまり考慮せず、システムに必要なエンティティとエンティティどうしの関係を洗い出します。

論理設計
概念設計で洗い出したエンティティを整理し、各エンティティが持つべき属性を洗い出します。この際に、データの重複をなくし、整合をとるために「正規化」と呼ばれるデータの整理を行います。

物理設計
実際にデータを格納するDBMSやDWHに合わせた設計を行います。各エンティティや属性の名前・形式を決定、主キーの設定、インデックスの設定などを行います。

5.5 アジャイル開発と設計
アジャイル開発の手法にもいくつかありますが「スクラム」と呼ばれる手法が代表格で、これによるアジャイル開発の特徴は概ね以下のようになります。
- 全てを一度に開発するのではなく、小さい単位に分け、短いサイクルで計画・設計・実装・テスト・デプロイを行う。これを反復することにより、漸進的に開発範囲を増やしていく。
- ソフトウェアはこの反復ごとにユーザに提供され、得られたフィードバックを次のサイクル以降で反映する。
- 短いサイクルで迅速に開発を行うために、比較的小規模な「チーム」により開発を行う。コミュニケーション方法としてはチーム内での対面での会話を重視する。
- ドキュメントよりも実際に動くソフトウェアを見せることによって、関係者の共通理解を得ることを目指す

アジャイル開発では、最初に「仮説」を立て、スクラムを通じてここの仮説が正しいかを検証し、修正していきます。システム設計の観点からアジャイルを見ると、アジャイルにおける「設計」はあくまでも仮説であり、実際に開発を行うことで仮説を検証していくことになります。
ただし、上流設計の全てを「仮説」とみなしているかというとそういうことではありません。通常アジャイルが適用できるケースは、以下の場合です。
- 非機能要件がすでに決まっている(あるいは自明である)
- システムアーキテクチャがすでに決まっている(あるいは自明である)
つまり、最上位の設計において「仮説」となり得るのは要件定義の「機能要件」のみです。Web型のシステム開発にアジャイルがよく使われるのは、非機能要件、システムのアーキテクチャはすでに決まっている(あるいは自明)な場合が多いためです。