【初心者向け】システム開発をする際に知っておきたいあれこれ(開発の流れ、開発手法、テスト、モジュール等)

エンジニアの主な仕事の1つに『システム開発』があります。
システム開発を簡単な言葉に言い換えると『便利な仕組みを作ること』です。
より具体的にいうと『手作業で行なっていた在庫管理の業務を、パソコンで自動で管理できるようにする』などがあります。

まさにエンジニアのイメージ通りの仕事内容といえるシステム開発は、たくさんの人の苦労を軽減させたり多くの人を幸せにすることができたりと、やりがいも達成感も抜群にある仕事内容です。
しかしいきなり『便利なシステム作ってよ！』と言われても
・システム開発ってどんな流れで開発したらいいの？
・どんな開発手法があるの？
・どうなったら完成したと言えるの？
などを知らなければ、何から手をつけていいのか分からず困ってしまうでしょう。

個人やチームによって多少違いはあれど、大まかなシステム開発の流れや内容は共通ということで、[『キタミ式イラストIT塾 基本情報技術者 令和03年』](https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C03%E5%B9%B4-%E3%81%8D%E3%81%9F%E3%81%BF%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297117819)の内容を参考に『システム開発』について学習したので備忘録として残しておきます。
#システム開発の流れ
ソフトウェアライフサイクル・・・『①企画』『②要件定義』『③開発』によって作られたシステムが『④運用』『⑤保守』を繰り返し働き続けること。
###企画 / 要件定義
企画段階で検討すべき項目
　↳スケジュール・・・導入までの具体的な期間や段取り。
　↳体制・・・どれくらいの人数をかけるか、誰を担当にするか。
　↳リスク分析・・・どんなトラブルや損害が発生する可能性があるか。
　↳費用対効果・・・かかる金額に対して見合ったリターンが見込めるか。
　↳適用範囲・・・どんな業務をシステム化するか。

要件定義・・・どのような機能を持ったシステムが必要なのかを固めること。これをしないと開発依頼がだせない。
###開発の流れ
調達・・・依頼者（クライアント）が開発を受注する側（システムベンダ）に対して発注をかけること。契約締結までの流れと文書のやり取りは以下のようになる。
　↳①情報提供依頼・・・システムベンダに情報提供依頼書を渡して、最新のシステム導入事例などの提供を依頼する。
　↳②提案依頼書の作成 / 提出・・・発注側がシステムの内容や予算などの条件をまとめた提案依頼書をシステムベンダに提出する。
　↳③提案書の受け取り・・・システムベンダから具体的な開発内容をまとめた提案書を発注側に渡す。
　↳④見積書の受け取り・・・提案書の内容に問題がなければ開発や運用・保守にかかる費用を見積書にまとめて発注側に渡す。
　↳⑤契約締結・・・提案内容や見積書の金額を確認し、発注者側が依頼をするかどうかの決定をする。

###開発の大まかな流れ
　↳①基本計画（要件定義）・・・利用者へのヒアリングなどを行い、求められる機能や性能をまとめる。
　　↳②システム設計・・・要件定義の内容を元にシステムの詳細な仕様を固める。複数の段階に分け、大枠から詳細にかけて決める。
　　　↳③プログラミング・・・プログラミング言語を使って設計通りに動くプログラムを作成する。
　　　　↳④テスト・・・作成したプログラムにミスがないかを調べる。設計と逆の順序で詳細から大枠にかけて検証していく。
　　　　　↳⑤導入 / 運用・・・テストに問題がなければ発注元にシステムを納入し、運用を開始する。

###①基本計画（要件定義）
作成するシステムにどんな機能が求められているのかを利用者へのヒアリングによって明確にする。要件を取りまとめた結果は『要件定義書』という形で文書にまとめる。

###②システム設計
要件定義の内容を具体的なシステムの仕様に落とし込む。システム設計は『外部設計』『内部設計』『プログラム設計』の３つの段階に分けられる。
　↳外部設計・・・システムを実際に利用する人の目線で見た設計をする。入力や出力などのユーザインタフェースの部分を設計する。
　↳内部設計・・・システムを開発者の目線で見た設計をする。外部設計を実現するための実装方法やデータ管理方法などの設計を行う。
　↳プログラム設計・・・プログラムをどう作るかという目線で設計する。プログラムの構造やモジュール（システムの構成要素）同士のインターフェース（接点）仕様などを決める。

###③プログラミング
システム設計で決めた内容にしたがって、プログラムをモジュール単位で作成する。作成の際は様々なプログラミング言語を用いる。
　↳プログラマ・・・プログラムを書く人のこと。
　↳プログラミング・・・プログラムを書く作業のこと。
　↳ソースコード・・・プログラミングによって書かれた中身のこと。
　↳プログラミング言語・・・ソースコードを書く際に使用した言語のこと。
コンパイラ方式・・・ソースコードを機械語に翻訳する際に最初から全部翻訳してから実行する方法。
インタプリタ方式・・・ソースコードを機械語に翻訳する際に逐次翻訳しながら実行する方法。

###④テスト
作成したプログラムにミスがないかを検証する。『単体テスト』『結合テスト』『システムテスト』『運用テスト』の４つの段階に分けられる。
　↳単体テスト・・・モジュール（構成要素）単位での動作確認を行い、プログラム設計通りにできているかを確認する。
　↳結合テスト・・・モジュールを結合させた状態での動作確認や入出力検査を行い、内部設計通りにできているかを確認する。
　↳システムテスト・・・システム全体を稼働させて動作確認や負荷試験を行い、外部設計通りにできているかを確認する。
　↳運用テスト・・・実際の運用と同じ条件下で動作確認を行い、要件定義の要求仕様が満たされているかを確認する。
#代表的なシステム開発手法
###ウォータフォールモデル
要件定義→システム設計→プログラミング→テストの流れで各工程を順番に進めていく手法。
　↳メリット・・・それぞれの工程を完了させてから次に進むので管理しやすく大規模開発などで広く使われる。
　↳デメリット・・・利用者がシステムを確認できるのが最終段階に入ってからなので、修正（手戻り）が必要になるととても大変。

###プロトタイピングモデル
開発の初期段階（要件定義とシステム設計の間）で試作品（プロトタイプ）をつくり、それを発注者に確認してもらうことで意識のズレを防ぐ手法。
　↳メリット・・・発注者が早い段階でシステムに触れて内容を確認できるので、後からの手戻りが起きにくい。
　↳デメリット・・・プロトタイプを作るのにも手間がかかるので、あまりにも大規模なシステム開発には向かない。

###スパイラルモデル
システムを複数のサブシステムに分割してそれぞれのサブシステム毎に、ウォーターフォールモデル形式で開発を進めていく手法。
　↳メリット・・・完成したサブシステム毎に発注者に確認してもらえるので、後になるほど手戻りが起こりにくくなり開発効率が上がる。
　↳デメリット・・・工程が多数に分かれるので開発全体の複雑さが増すので管理が大変になる。

###レビュー
開発作業の各工程が完了した際に問題がないか振り返り作業を行い検証することで、潜在する問題点を早めに発見し次の工程に持ち越さないようにすること。
　↳デザインレビュー・・・設計段階で作成した仕様書に対して不備がないかを確認し、設計の妥当性を検証するためのレビュー。
　↳コードレビュー・・・作成したプログラムに不備がないかを確認するために行う、ソースコードを対象としたレビュー。
　↳ウォークスルー・・・開発者や作成者が主体となってプログラムや設計書のレビューを行う方法。問題点の早期発見が目的。
　↳インスペクション・・・第三者であるモデレータをレビュー責任者として参加者の役割を決めて行うレビューの方法。
　↳ラウンドロビン・・・参加者全員が持ち回りでレビュー責任者を務めながらレビューする方法。参加者全員の参画意欲を高める効果がある。
#その他の様々な開発手法
RAD・・・エンドユーザー（最終的に商品を使う人）と開発者で少人数のチームを組み、短期間で開発を行うことを重要視した開発手法。

アジャイル・・・スパイラルモデルの派生型として、より短い単位で開発を行う手法の総称。
　
XP・・・早めのタイミングでサービスをリリースしてしまい、変更点や修正点を後からどんどん追加していく手法。
　
リバースエンジニアリング・・・既存のソフトウェアを解析することでプログラムの仕様やソースコードを導き出すこと。

フォワードエンジニアリング・・・リバースエンジニアリングによって得られた仕様をもとに新しいソフトウェアを開発する手法のこと。

マッシュアップ・・・公開されている複数のサービスを組み合わせることで、新しいサービスを作り出す手法のこと。
#業務のモデル化
業務のモデル化・・・現状の業務プロセスを抽象化し視覚的にあらわすことで、業務に関わっている人物や書類の流れをはっきりさせること。

DFD・・・『Date　Flow　Diagram』の略で、データの流れを図としてあらわしたもの。

E-R図・・・実体（Entity）と関連（Relationship）という概念を使って、データ構造を図にあらわしたもの。
#ユーザインターフェース
インターフェース・・・あるものとあるものの間に立って、そのやり取りを仲介するもの。

ユーザインタフェース・・・システムと利用者の間に立って、お互いのやり取りを仲介するもの。

CUI・・・『Character　User　Interface』の略。出力も入力も文字のみで、文字を打ち込むことで命令を伝えて処理させる方式。

GUI・・・『Graphical　User　Interface』の略。画面にアイコンやボタンを表示して、それをマウスなどで操作して命令を伝える操作方式。
###GUIで使われる部品
ウィンドウ・・・アプリケーションの基本領域。この上に部品を配置して操作画面を作る。

メニューバー・・・アプリケーションを操作するための項目が並んだメニュー。細かい操作がプルダウンメニューに格納されている。

プルダウンメニュー・・・クリックすると下に垂れ下がって表示されるメニュー。

ラジオボタン・・・複数ある選択肢の中から１つを選ばせるときに使う。

チェックボックス・・・選択肢を複数選択したり、特定の項目をオン/オフさせるときに使う。

テキストボックス・・・ユーザに自由に文字や文章を入力してもらう際に使用する。
###画面設計時の留意点
・入力は左から右、上から下となるように流れを統一する。

・画面上でいくつかの色を用いる際にはそれぞれの色毎にルールを持たせる。（注意を促す文章には赤色を使うなど）

・選択肢の数が多いときは選択肢をいくつかのグループに分けたり、階層化することで分かりやすくする。

・入力ミスに対してはエラーメッセージを表示し、原因と対処法を分かりやすく簡潔に表示する。

・画面毎の入力パターンやレイアウトを共通化する。

・操作に不慣れなユーザのために、ヘルプなどの操作説明を用意する。
#コード設計と入力のチェック
コード・・・人や商品、サービスにつける識別番号のこと。コードを割り当てることでたくさんの中から簡単に１つのものを探せたり、商品の並び替えや分類を簡単に行えるようになるといったメリットがある。

コード設計の留意点
　↳何をコード化の対象にするのかを明確にさせる。
　↳どのような規則のコードとするのかを将来予測を行った上で決める。
　↳コードの桁数を不足なく使いやすい範囲で何桁にするのか決める。

チェックディジット・・・誤入力を判定するためにコードへ追加する数字のこと。
###入力ミスのチェック方法
ニューメリックチェック・・・数値として扱う必要のあるデータに、文字などの数値として扱えないものが含まれていないかをチェックする。

シーケンスチェック・・・対象とするデータが一定の順序で並んでいるかをチェックする。

リミットチェック・・・データが適切な範囲内にあるかをチェックする。

フォーマットチェック・・・データの形式が正しいかをチェックする。

照合チェック・・・入力されたコードが、登録されているデータの中にあるかを照合してチェックする。

論理チェック・・・販売数と在庫数と仕入れ数の関係など、相互に関わり合う項目の値に矛盾がないかをチェックする。

重複チェック・・・一意であるべきコードなどが、重複して複数登録されていないかをチェックする。
#モジュールの分割
プログラムの構造化設計・・・各プログラムをモジュールという単位に分解 / 階層化させること。

データの流れに着目した分割技法
　↳STS分割法
　↳トランザクション分割法
　↳共通機能分割法

データの構造に着目した分割法
　↳ジャクソン法　　
　↳ワーニエ法
###モジュールに分ける利点 / 留意点
・作業が分担できる・・・複数人で並行してプログラミング作業を進めることができる。

・再利用が可能・・・共通する機能を部品として使い回すことができる。

・修正が一部分で済む・・・欠陥のあるモジュールを修正することで、プログラムの修繕が可能。

モジュールに分ける留意点

・モジュールの中にごちゃごちゃと、いろんな機能が詰め込まれ使いにくい

・モジュールの中身が他のモジュールに依存しており、一部を変更すると他のモジュールも動かなくなってしまう。
###データの流れに着目したモジュールの分割技法
STS分割法・・・プログラムを『入力処理』『変換処理』『出力処理』の３つのモジュールに分割する方法。

トランザクション分割法・・・プログラムを一連の処理（トランザクション）単位に分割する方法。

共通機能分割法・・・プログラム中の共通機能をモジュールとして分割する方法。
###モジュールの独立性を測る尺度
モジュールの独立性・・・そのモジュールがどれだけ機能的に明確で、かつ入出力がはっきりしているかということ。『モジュール強度』と『モジュール結合度』を用いて測る。
　↳モジュール強度・・・モジュール内の機能が内部でどのように関連づいているかを示す尺度。これが高いほどモジュールの独立性が高く望ましいと言える。
　↳モジュール結合度・・・モジュールがどんなデータをやり取りすることで、他のモジュールと結合するかを表すもの。これが弱いほどモジュールの独立性が高く好ましいと言える。
#テスト
テスト・・・作成したプログラムのバグ（記述ミスや欠陥）を各種検証によって洗い出し、改修を行うこと。
#参考文献
この記事は以下の情報を参考にして執筆しました。
[キタミ式イラストIT塾 基本情報技術者 令和03年](https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C03%E5%B9%B4-%E3%81%8D%E3%81%9F%E3%81%BF%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297117819)