個人で小規模な書籍自炊システムを作った、振り返りながらシステム開発の勘どころをまとめる。#1導入編

# 概要
この度、自分だけで使う小規模な書籍自炊システムを作った。
振り返ってみると**業務でのシステム開発**に通じる要素がちらほらあった。
初心者や未経験者、大学生など、システム開発に関してまだそれほど明るくない方に向けて勘どころをまとめる。
まず、この記事ではシステム開発の一般的な情報を広く浅くまとめていく。
また、顧客向けサービスや社内システム、受託開発、自社開発などを区別せず広い意味で**システム開発**を取り上げる。
IT関連の仕事に興味があるががなんとなく実態が掴めない、具体的な業務内容がピンとこない、という方が解像度を上げる助けになれば幸いである。\

# 目次
[導入](#)(この記事)
[要件定義](https://qiita.com/kettle/items/dc4603795457cbe4dc12)
[設計](https://qiita.com/kettle/items/49a38558cf4a645f7659)
[実装](https://qiita.com/kettle/items/a06a11cfda8d8432a948)

# システムとはどんな言葉か
一般的に**システム**というとコンピュータが何らかの処理をするものという印象がある。
もちろん間違っていはいないが「**ある目的のために人間とコンピュータが関わる一連の仕組み**」という方がより本質的である。

例えば今回の書籍自炊システムでいえば、本をめくったりスキャンボタンを押したりという部分は人間の仕事である。
一方でスキャン処理そのものや、スキャン結果のPDF出力などはコンピュータの仕事といえる。
人間とコンピュータの仕事が合わさってシステムが成り立つと考えるのがベター。

# プロジェクトとはどんな言葉か
あるシステムを作る、となったときにその開発に関わる一連の事柄を指す言葉。
「新しいプロジェクトに参加する」とか「プロジェクトの進行管理を担当する」というような使い方をする。
**案件**とも言い換えられるし、文脈によってはそのまま**システム開発**とも言い換えられる。

# その他システム開発に関わる言葉
ごく簡単ではあるが、その他システム開発に関わる言葉を次の図にまとめた。
初心者でも聞いたことがあるような言葉を選んでいる。
図の上方をプロジェクト初期として下方に進んでいく。また、左がより開発側で右がユーザー側の配置とした。
それぞれの言葉には幅があり、図の中で上下したり左右したりする。
![システムに関する言葉.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874887/171b47ea-7e2a-b491-f77d-9ff11a66ebf8.png)
※ PG(プログラマ) SE(ソフトウェアエンジニア) PM(プロジェクトマネージャー)

この図から例えば次のようなことが読み取れる。
- PMはあまりコンピュータ的な業務に関わらず、プロジェクトの管理やユーザーと話し合う業務が多い。
- SEはPGとPMの橋渡し、PMは開発チームとユーザーの橋渡し的な役割がある。
- PGは**要件定義**の工程、ユーザーは**設計**や**実装**の工程ではほとんどやることがない。

# 各工程について
それぞれの工程の概要は以下の通り。

## 要件定義
プロジェクトの初期段階、ユーザーとPM、SEでの打合せが多い。
ユーザーといっても**実際にそのシステムを使う人**(現場作業者)が打合せに参加するのは稀で、基本的にはユーザー側の偉い人だったりIT担当者が参加する。
そのためプロジェクトによっては必要な要件が見えてこない場合があり、開発チームの手腕が試される。
システムが無事完成していざ運用してみると現場から不満が上がってくるのはこのため。
振り返ってみると要件定義の時点で間違っていた、というのはよくある話。

## 設計
要件定義が終わったら(または要件定義の最中に)仕様を作り始める。
どんな入力をして、どんな処理をして、どんな出力をするかを形作っていく段階。
画面があるシステムであれば画面のレイアウトだったりボタンを押したときの動きを決める。
画面がないシステムであればどんなコマンドが必要か、何をトリガーとして処理を始めるか、などを決める。
また、このときに**出来ること**はもちろん**出来ないこと**も決める。
例えば「この処理はこういうデータを前提とする、それ以外はエラーを出す」といった感じ。
ここでいろいろな〇〇設計書が作られる。
仕様が出来上がったらユーザーから承認を得て実装工程に進む。

## 実装
ここがいわゆるプログラミングの工程、コードを書いたりデバッグをしたりという段階。
この段階を開発工程と呼ぶこともあるが、今回は分かりやすさのために実装工程と呼ぶ。
設計書をもとに実際に動くモノを作っていく。
ほとんどの場合この後にテスト工程を行うが、今回は分かりやすさのため実装工程にテストを含めている。

## 保守・運用
システムが完成してユーザー側の現場で実際にシステムが使われる段階。
運用は文字通りシステムを使ってユーザーが業務を進めること。
保守はシステムのアップデートやバグ修正を行うこと。

# 各役割について
それぞれの役割の概要は以下の通り。

## ユーザー
システム開発を依頼する人たち。
今回は**ユーザー**として一括りにしているが決裁者(役職者)やIT担当者、現場作業者など様々な人が含まれる。
要件定義の説明にも書いたが、プロジェクトに関わってくるのは決裁者やIT担当者が多い。
プロジェクトの進行に応じてIT担当者が現場作業者の意見や要望を取りまとめて、開発チームとの打合せに参加するのが一般的。

## PM(プロジェクトマネージャー)
ユーザーと話し合ったり、開発チームと話し合ったりする役割。
また、プロジェクトの進行管理や品質管理もする。
より具体的に言うとエクセルやパワーポイントを一番使う人。
マネジメントが主な仕事で、自分でコーディングすることはほとんど無い。
人によっては過去にプログラミングの経験が無く、コードの読み書きが出来ない人もいる。
ただし、プログラミングやテクノロジーに関する知識はあればあるほど良い。
年齢層は30代以上が多い印象。

## SE(システムエンジニア)
設計をしたり実装結果を確認したり、広い意味のプログラミングをする役割。
ユーザーとの打合せに参加することも多い。
ユーザーやPMと話し合いながら、ときにはPGと協力しながら設計や実装を行うようなイメージ。
自分で設計とコーディングを両方することもある。
20-30代が多い印象、新卒エンジニアがこの役をやることもある。

## PG(プログラマ)
主に実装をする、狭い意味のプログラミングをする役割。
環境構築を始めコーディングやDB作成など、**動くモノ**を作るために必要なすべてを行う。
**ITエンジニア**と聞いて一番想像しやすいのは恐らくこの人たち。
こちらもSEと同じく20-30代が多い印象、新卒エンジニアがこの役をやることもある。

:::note info
**日本のシステム開発の特徴**
日本のIT業界の特徴として若手はSEやPGをやって昇進したらPMをやるという習慣が挙げられる。
これは恐らく、SEやPGは手を動かして仕事をする事が多いのに対して、PMはマネジメントが主な仕事というのが一因だろう。
マネジメントは職位が高い人がやるもの、という考えが背景にあるのだと思う。結果としてSEやPGは20-30代が多く、PMはそれ以上の年齢層が多くなっていく。
最近はあまり聞かなくなったが**ITエンジニア35歳定年説**という言葉も存在する。
ただし、昨今の人手不足や時代の流れもあいまってここ数年ではこのような習慣は減少傾向に感じられる。
:::

# 開発手法
開発手法にはアジャイル開発やウォータフォール開発、テスト駆動開発、ドメイン駆動開発など様々な手法がある。
よく聞くのはアジャイル開発やウォータフォール開発。
大まかに説明すると、それぞれの開発手法は**プロジェクトの進め方**が異なるが、主な違いは次の工程の回数や順番が異なる点である。
- 設計
- 開発
- テスト・レビュー

例えばアジャイル開発は最初に必要最低限の機能から作り始めてユーザーからのレビューを反映、再設計、実装を繰り返していく。
要件が決まりきっていない小規模なプロジェクトに向いていると言われている、設計・実装・テストを1つの括りとして数週間ごとに繰り返していく。

また、ウォータフォール開発は最初にシステム全体を設計して実装、テストというように一本道で進んでいく、繰り返しはしない。
銀行など要件が決まっている大規模なプロジェクトはこの開発手法が多い印象がある。こちらは設計・実装・テストを1つずつ数ヶ月ごとに進めていく。

今回の書籍自炊システムはどちらかといえばアジャイル開発ということになる。

## 実際は……
余談だがウォータフォール開発は分かりやすい燃え方をすることが多い。要件が決まっているため工期が最初からきっちりと定められているが、実際には予定通りに進まず手がつけられなくなる、という印象。
対してアジャイル開発は分かりにくい燃え方が多い。最初にゴールを明確に決められればよいのだが、開発を進めていくうちにゴールを見失って「これいつリリースすの？」となっていく印象。

ただし「アジャイル(またはその他の手法)で開発します！」と言ってもその手法通りに最後まで進むプロジェクトはあまり多くないように感じる。
ユーザー、開発チーム、その他の要因で途中から成り行きで進んでいくプロジェクトもよく見かける。
PM(プロジェクトマネージャー)はある程度これらの手法を意識したほうがよいが、一般的なメンバーレベルのエンジニアとしてはなんとなく理解しておけばよいとさえ感じている。
状況にあわせて開発の足並みを揃えられる方が大切かなというのが個人的な考え方。

# システム開発はなぜ失敗するのか？
業務でのシステム開発はよく失敗する、なぜか。
これには開発規模や予算など様々な要因があるが、外せない要因として**プロジェクト参加者が他人事と思っている**というものがある。

## ユーザー側の視点
例えばユーザー側からプロジェクトに参加するのはどのような人か、役職者やIT担当者が参加するケースが多い。
まずこの人たちは自分が実際にはあまり使わないシステムを作ることになる。
上司に言われたから、とか現場からの要望で、とか理由は様々だが**これから作るものをよく分かっていない**のである。
ただしこれはあまり問題ではない。
ユーザー側が最初から細かい要件を提示できる方が珍しい、そのために要件定義の工程があるのだ。

## 開発側の視点
では開発側を見るとどうだろうか。
開発チームの姿勢としては**ユーザーが作りたいものを作る**というのが基本である。
開発チームが作りたいものを勝手に作ってはいけないのだ。
もちろんこれもあまり問題ではない。
ビジネスとしてユーザーから報酬を受け取って開発するのだから当然である。

## 結果として
運悪くこの状態の両者が同じプロジェクトに集まってしまったらどうだろうか。
ユーザーは**これから作るものをよく分かっておらず**、開発チームは**ユーザーがよく分かっていないものを作る**ことになる。
こうなってしまうと炎上は避けられないし、運良くシステムをリリースできても失敗という評価に終わるだろう。

## 望ましい状態とは
ユーザー側はユーザー内でよく話し合い、システムの全体像やユースケースをはっきりさせる。そして積極的に開発側に伝える。
開発側はユーザーから本当に必要なものを聞き出す、ユーザーの要件が曖昧であればサンプルなどを作って解像度を上げていく。
実際に動くモノがあれば「このサンプルよりはこういうものがほしい」とか、「全体的には良いけどここを直してほしい」など認識を合わせやすくなる。
ユーザー側も開発側も**自分ならこう考える**というのを出し合って同意を得ていけば、**明らかに変なものを作って大失敗する確率は下がっていく**だろう。

# まとめ
この記事ではシステム開発の一般的な情報を広く浅くまとめた。
次の記事からは、今回開発した書籍自炊システムについて具体的な内容に移っていく。
要件定義や設計、実装など**それぞれの工程で実際にやったこと**や、**業務でのシステム開発ならばこうする**、ということを書いていきたいのでぜひそちらも読んで見てほしい。