No.8 新卒未経験エンジニアが開発プロセスを分解してみた〜第2章　設計〜

前回の第1章　要件定義に続いて第2章　設計です！

要件定義という試練を乗り越えて次に待ち構える設計という試練。
設計という段階でもやることが多く、まず何をすれば良いか分からない。。
そんな時にこの記事を思い出してもらえれば幸いです。
それでは第2章入っていきましょう。

## 目次
[第1章　要件定義](https://qiita.com/kosuke_aizawa/items/90e6e97c56e0795568d6)
第2章　設計　←今回はココ！
[第3章　開発（実装）](https://qiita.com/kosuke_aizawa/items/a04ddd856b85eca99d72)
[第4章　テスト・検証](https://qiita.com/kosuke_aizawa/items/595892040d808acd6123)
[第5章　リリース](https://qiita.com/kosuke_aizawa/items/a53e115d9ea78cb859d1)
[第6章　運用](https://qiita.com/kosuke_aizawa/items/0228e289958659cdcf87)

## 設計ってなんだ？？
設計と聞いて、どんなことをやるのか全くイメージ湧かない！
という方はいないと思います。
きっと今までの人生で何かしらの設計をしたことありますよね！
例えば、前回出した旅行の例で見てみましょう。

来週末、友人たちと城崎温泉に旅行に行くことになりました。
日頃の疲れを癒すため、現地で温泉巡りをして美味しいものをたくさん食べてリラックスしたいと思ってます。
旅行の計画を立てるために、友人たちと集まって話し出しました。
「お昼すぎには着きたいから午前中には出発したいね！」
「そしたら11時15分の電車があるから１１時に京都駅集合にしようか」
「現地に着いたら先に旅館にチェックインして、一息着いたら温泉巡りしよう！」
...etc

このように、「城崎温泉旅行」の詳細を決めていくのが設計に当たります。
開発プロセスにおける設計も同じで、要件定義で決めたものの実現に向けてその中身を詰めていきます。
旅行などの身近な例では分かりやすいと思います。
ですが、開発を行う際の設計プロセスでは何をすれば良いか明確に分かってないという方もいらっしゃるのではないでしょうか？
今一度、設計でやるべきことを見直してみましょう。

## 設計の目的…を念のため確認しておきましょう！
さて、今更ですが設計を行う目的は何でしょうか？
こんなこと聞かれなくても分かってる方がほとんどでしょうが、きちんと目的をブラさないためにも確認しておきます。
要件定義の目的ではこのように書きました。

**依頼者（発注者）にとって本当に価値のある成果物を提供すること**

実はこれってそもそも開発をする目的でもあるんですよね。
つまり開発を構成する要素である、要件定義や設計の目的も最終的にはここに繋がってきます。

結局要件定義と同じく、設計を行う目的も

**依頼者（発注者）にとって本当に価値のある成果物を提供すること**

ということですよね！！

## 設計のゴールとは！？
無事目的を確認できたところで、設計のゴールは何？というところを深堀りしていきましょう。

みなさんプラモデルは作ったことありますか？
ガンプラなんかは作ったことある方いるのではないでしょうか！
僕は手先が不器用すぎて接着剤まみれにしてしまったり、部品を折ってしまったりと、うまくいった覚えがありません笑

プラモデルて、完成像やどんなことが出来るか（可動式のパーツがある場合、動かしてポーズをとったり）、それを部屋に飾った時の部屋の雰囲気、見え方などは作る前から容易に想像出来ると思います。
その想像が、よりカッコ良いものを作ろうとするモチベーションにつながると思います。
では実際に製作を始める時にまず何をしますか？
おそらく説明書を読んで、
・どんな材料が必要か
・どんなパーツがあるのか
・どうやって組み立てていくのか
などを読むのではないでしょうか？

逆に組み立ての説明書がなければどの部品をどうやって組み合わせて作り上げていけば良いかも分かりません。
もしかしたら不備で部品が足りないかもしれません。
そうなったらいくら頑張っても完成しませんよね。

説明書にしっかりプラモデルを完成させるのに必要な情報が全て記載されているため、作ることができるのです。

ここまでくれば設計のゴールはお分かりでしょう！
そうです！
ドキュメントを残すのです！
システム設計書を作成することで、依頼者と開発者の間で共通認識を取ることが出来ます。
また、開発は複数人で行うことが多いため、複数人が同じ認識を持つ必要があります。
そんな時にシステム設計書があることで共有がスムーズになるというメリットもあります。

まとめると、設計のゴールは

**要件定義を設計書に落とし込むこと**

と言えると思います！！

## 設計段階でやるべきこと
開発の説明書にはどのような情報があれば良いのか気になりますよね！
どこまで設計するのかは結構人によって違ったり、会社によっても違ったりします。
なのでこれから書くことが全てではありません。
大切なことは上記の目的と目標をブラさないということです。

設計には以下の2種類に分かれます。
・**外部設計**
　→システムの外側でユーザーやクライアントの目に触れる部分（インターフェース）、システム全体の概要、主な機能を設計
・**内部設計**
　→システムを開発するときに必要な部分やシステムの裏側（内部）でデータがどのように処理されているのかなど、ユーザーにもクライアントにも見えない部分を設計

第1章で出した親友の恋愛相談の話の続きです。
親友から恋愛相談を受けたあなたは無事、親友に合いそうな相手を何人かピックアップしました。
そこで親友には事前情報として、相手の写真や性格、趣味などの情報を伝えました。
「何人か候補がいるんだけどどの人が好み？」
「この人とか良さそう！コンパセッティングしてよ！」
「了解！雰囲気の良いお店、例えば個室のイタリアンなんか予約しておこうか！」
「そうだね！静かなところがいいな！予算は一人5000円くらいで探してくれる？」
「了解！」

家に帰ったあなたはこんなことを考えました。
（みんなの予定調整しないといけないな。今週中にお店探して予約しておかないと。嫌いなものないかどうかも確認しておこう！）

こんな良い人が親友にいたら一生大切にすべきですよ笑
さて、実はこの時無意識に外部設計と内部設計を行っているんです。

相手の写真と情報を見せて、当日連れてくる人を決めたり、コンパのお店を絞ったり、直接親友の目に触れる部分を決めていく。
これが外部設計です。
それに当たって、全員から予定を聞いて調整したり、嫌いな食べ物を聞いておいて当日料理で出てこないように調節したりと、親友が直接目にする訳ではない裏側の部分を決めていく。
これが内部設計に当たります。

何となくイメージ湧きますよね！
では、具体的に外部設計、内部設計ではどんな設計をしていくのか以下にまとめました。

・外部設計
　- アーキテクチャ設計
　- DB設計
　- UI設計
　- バッチ設計

・内部設計
　- 機能分割
　- 物理データ設計

それぞれ簡単に説明していきます。
詳しい内容まで書き出すとえぐい量になる&僕自身詳しく分かってないので割愛させて頂きます。

### 外部設計
#### アーキテクチャ設計
アーキテクチャ設計では、開発するシステムの基盤の設計を行います。
システムに要求されている機能・性能を、システムを構成する要素に配分して構成要素の仕様を明確にします。
先ほどの例でいうとコンパのお店を探して決める、といったことです。

参考になりそうなサイト：[Webアプリ構築で、まず考えるべきアーキテクチャの検討ポイント（基礎編）](http://www.atmarkit.co.jp/ait/articles/1405/10/news001.html)

#### DB設計
そのシステムはどのようなデータを持っているかを洗い出して、整理します。
データをどのように分割して持つか、などのデータの持ち方も設計します。
先ほどの例でいうと、お店の場所・時間・予算などはLINEのノートに投稿して保存しておく、などです。

参考になりそうなサイト：[4ステップで作成する、DB論理設計の手順とチェックポイントまとめ](https://qiita.com/nishina555/items/a79ece1b54faf7240fac)

#### UI設計
いわゆる画面設計です。
実際に開発するシステムがどんな画面構成かを考えます。
ボタンの配置などのユーザーの使いやすさを考え、細かく決めていきます。
相手の写真を見せてどの人を紹介してもらうかを決める、といった行動がそれに当たります。

参考になりそうなサイト：[UIデザインを考える上で重要な4つのポイントとは](https://blog.codecamp.jp/ui-design)

#### バッチ設計
システムによっては、データの生成やデータの処理をリアルタイムでやらない方が良い場合があります。
サイトのログを集計してサイト分析する処理などはリアルタイムでやると処理が重くなり、UXに影響します。
そういう場合はバッチ処理にしてしまい、裏で回すことでUXに影響を与えることなく、実装できます。

参考になりそうなサイト：[多い日も安心設計](https://qiita.com/kawasima/items/ee863f23b4588b9792fb)

### 内部設計
#### 機能分割
こちらではよりプログラミングに近い設計を行います。
システムを機能単位で分解して、それぞれの機能ではどのような処理を書くかを設計していきます。
究極は内部設計書の内容をコードに落とし込むだけで良い状態になります。
そこまで整理してまとめるのはおそらくかなり時間がかかるので、スピードを重視したい場合は機能と処理を簡単に洗い出す程度にしても良いかと思います。

参考になりそうなサイト：[内部設計](http://www8.plala.or.jp/a_ITC/Internal_Design.htm)

#### 物理データ設計
あまりここの設計の内容が調べても分からなかったので一旦それっぽいサイトから引用してきました。
上記、機能分割で紹介した参考になりそうなサイトから

```
外部設計で行った論理設計を前提として、
使用するシステムの環境やファイルの特性等を考慮し、ファイル編成の方法や媒体、レコードのレイアウトを決定する。
（ファイル編成方法の決定 ⇒ ファイル媒体の決定 ⇒ レコードレイアウトの決定） 
　　・　データのライフサイクル（半永久・年単位・半年・月単位・週単位・日単位・一時等）を決定。
　　・　更新特性（検索・挿入・更新・削除）や１日の更新量を決定する。
　　・　現在のデータ量、ライフサイクル、更新特性、１日の更新量を考慮し、数年後のデータ量を見積る
　　・　I/Oが分散する様に配置する。
　　・　更新特性を考慮しながら、初期ロード時の領域使用率を決定する。
　　・　アクセスパスを考慮しながら、インデックスを設定する。
```

要するに外部設計で行ったDB設計とは違い、データの扱い方的な部分での設計かな、と思います。
このテーブルには毎日このくらいのデータがinsertされるから、◯ヶ月後にはどのくらいのデータ量になるからデータベースの容量はこのくらいのものを用意しておこう、といったような設計のイメージです。

## まとめ
今回は設計を
・目的
・目標
・やるべきこと
の3点に着目してまとめました。

目的：**依頼者（発注者）にとって本当に価値のある成果物を提供すること**
目標：**要件定義を設計書に落とし込むこと**
やるべきこと：
**外部設計**
　- アーキテクチャ設計
　- DB設計
　- UI設計
　- バッチ設計

**内部設計**
　- 機能分割
　- 物理データ設計

要件定義と開発の間に挟まれる重要なプロセスなのですが、考える要素が多くて大変だ。。と率直に感じました。
設計を頑張りすぎると、設計で力尽きてしまいそうですね笑
あくまで設計が終わってからようやく手を動かしての開発のスタートです。
設計は大事ですが、色々決めようとしすぎて中々開発が進まないのも難儀です。
うまい具合に調整していかないといけないんだなぁ...

## 新卒未経験エンジニアの「設計」経験談
社内ツールを開発した時のこと。
ペーパープロトタイピングを行い、実際の画面を紙とペンで書き起こしました。
自信満々にPOに確認してもらいにいったところ、
「これ見にくくない？」
あっさり一言でぶった切られました。
今、その時のペーパープロトタイプを見た僕はこう思いました。
「これめっちゃ見にくいな。」