優秀者なエンジニアは、自分に間違えを気付かせるための手段をもってる (設計編)

自社でサービス開発をしていると納品というものはないので、どういう設計書を書くかはプロジェクト・会社様毎に違ったりします。書きすぎないドキュメントってなんだろうっと考えてるうちに、そもそも設計というフェーズはなんだったのかモヤモヤしたことをまとめてます。

　システム開発コストが大きかった昔は、失敗が許されないため設計というプロセスがあり、そのリスクを吸収しました。現在、開発スピードが求められるシステム開発において設計はどうあるべきか考えます。 設計とは大きく3つに分解でき、最後に残るのは【開発者の気付き】のための設計が残るように思えました。

システム設計が好きな人が増えるといいなぁっと思って書いてます。（つぶやいてます）
こんな人に読んでもらえると嬉しいです。
* 設計が好きな人
* 最小限のドキュメントで設計をしたい人
* プロダクトの品質をあげたい人


# システム設計を取り巻く変化

　昔々、システム開発というのは莫大な時間とお金がかかったものでした。
ムーアの法則で半導体性能が爆上がり！！ 20年前の19インチラックに収められたサーバが今やスマホ1台に収まる時代になりました。 

半導体だけじゃなくネットワークやフレームワーク、仮想化技術などが向上！
開発スピードもガンガン速度があがっていく！
開発コストもガンガン下がっていく！

莫大な時間とコストがかかっていたシステム開発が昔の1/10、、1/100のコストで作れるようになったのです。

システム開発コストが小さくなると、ビジネス変化に対応しやすくなり、変化に即時に対応する事が求められるようになってきました。システム開発に時間がかからなくなったので、すぐに作り直せばいいという開発スタイルがWeb業界を席巻しビジネスを牽引していきます。 

システム開発コストが小さくなり、リスクが少なくなったので設計が必要ないっていう時代が到来したのです。
(言い過ぎ！！！）

#### システム設計の役割を分解します
なんのためにシステム設計書くのかと言われたらこの3つではないでしょうか？
* 合意・指示書・方式として共有される
* 構造を可視化し、システムの役割を明確化する
* 情報が正しく振る舞うか確認する

それぞれの役割の現在地を説明し、どの工程にコストをかけるのか考察できたらと思います。



## 合意・指示書・方式として共有される
　ウォーターフォールでの開発で工程毎に開発組織が変わったします。要件を決める会社、設計をする会社、実装する会社、テストをする会社。現在でも大きいプロジェクトだと、このような開発スタイルをする事はあると思います。先程書いたようにリスクが高い開発プロジェクトだと設計でそれを吸収するというプロセスを踏むためそのようになります。 

　現在はどうでしょうか。システム開発にかかるコストは下がっていますので、昔に大規模と言われていたシステムは、今だと中規模、中規模といわれていたシステム開発は、小規模とシステム規模も相対的に小さくなってます。開発チームも小さくなり、AWSを開発者が使って、テストも自動化をエンジニアが行ってというプロジェクトは増えているのではないでしょうか？ 開発チームが大きくない限りは、設計書のこの役割の必要性は少なくなっていると思って良さそうです。 また、要件を合意したら、翌週には、もうビジネス要件が変わってる！なんてこともあると思います。こまめにスプリントレビュー時にフィードバックをもらうがいいと思います。

　画面設計書といわれれるものに、入力項目とデータベースの項目をマッチングさせるような内容文書を書いている現場もあると思いますが、これは指示的な役割が多いと思います。振る舞いを定義する、ユーザ価値を定義する、情報設計をする、UXを定義する、何一つ書かれてないものを設計書と呼んでいいものでしょうか？ 「ピザ2枚の法則」はこういう設計を変えるものであったりするチーム規模だったりしてます。 もしドキュメントを書くとしても、どのような課題あり、どのような手段で解決するのかという事が伝わる文書・図でありたいです。

小規模開発やスクラムでは、この指示的なドキュメントの必要性は低くなっていると思います。

## 構造を可視化し、システムの役割を明確化する

ここには２つの文脈があります。いずれも今も昔も必要だと思っています。
* アプリケーションアーキテクチャ設計
* システムアーキテクチャ設計

#### システム・アーキテクチャ
　複数のシステムをまたぐような仕組みを可視化し、適切な役割を持ったサーバなのか判断するプロセスは昔からありました。ジョブ管理やサブシステム、複数のプロダクトの連係など業務分析を行い概要システム設計レベルで行う事が多いように思えます。非機能要件を満たすためのシステム設計などは、ビジネス・プロダクトの成長にそって今も大事な設計な要素ではないでしょうか？ システムの拡張性を考慮した未来設計などは、実装するわけではありませんし仮説検証が必要です。

　現在は、ここの役割の必要性が高まっていると感じてます。マイクロサービスやドメイン駆動設計などでコンテキストマップなどを書きながら設計を進めていると思います。 コンテキストをまたぐ役割が明確になればこそ、マイクロサービスで作っているプロダクトが開発スピードを維持しながら作れると思えます。 いわゆる、インターフェイス仕様書の役割もAPIをつくる事が多くなり、シーケンス図を書きながらチームをまたぐコミュケーションをするなど機会が増えているのではないでしょうか？ 

#### アプリケーション・アーキテクチャ
　アプリケーションの内部構造の設計は賛否あると思います。自分はコードに表現されている事が望ましいと思っています。

　今の時代でオリジナルなフレームワーク、オリジナルなパッケージ構造を作るのは、開発スピードを落とす事になると思うので独自フレームワークなどは極力作らないと思います。新しく参入するメンバーも辛いでしょう。 
Googleで検索すればでてくることも多いのです。いわゆるプログラム設計なんてものは必要ないと思っています。 

ドキュメントをつくるより、コミュニケーション重視・レビュー重視で進めて、半年に1回ぐらいふりかえりも兼ねてドキュメントをつくるスプリントを作ったらどうでしょうか？ ドメイン駆動設計のレイアードアーキテクチャでつくるとか、オニオンアーキテクチャでつくるとかパッケージ名のルールをつくるとか最初に設計するべきものはありますが、設計・ルールを作りすぎると「守らせる」という謎の業務が発生する事になるので、設計・ルールは少ない方がいいです。

このレイアのトレンドがアジャイルは「コードが設計」という話しが発生した潮流なのだと思います。（違うかな）


## 情報が正しく振る舞うか確認する
 
　基本設計で要件トレーサビリティマトリックスなどを使って、要件とシステムとの関連が漏れてないかチェックする仕事をした事がある人もいると思います。ユースケース図、ロバストネス図や、データフロー図、データベース設計や、シーケンス図、コンポーネント図、CURD図や、状態遷移図、システム内で扱う情報をパターンを可視化したマトリックス図などなど、システムを表現するドキュメントは開発手法やプロジェクトによって様々ありました。

　最近ではどうでしょう。前述したように、小規模化、アジャイルで進めているプロジェクトではあまり書かなかったりしますか？（印象）。プロダクトや会社によると思いますが、UML系の書籍が最近はあまりでてない事を考えると、、、設計ドキュメントというものはあまり書かれてないのではないかと思っていたりします。 自分はスクラムでソーシャルメディアのグロースに関わっていたときは書いてませんでした。 そしてグロースしているうちにシステムが肥大化しメンテナンスが辛くなっていく、、、そんなシーンもあるのではないでしょうか？

ドメイン駆動設計をやってる現場ではドメインモデルを作って、コード変えて、ドメインモデル作って、コード変えてというようにサイクルで設計している人もいます。 これも情報を正しく振る舞わせるための構造を作るための手段だと思います。ドメイン駆動のドメインモデルというのはドメインエキスパートと共有し、気付いてないドメイン知識に気づくための手段です。

そもそも、設計書は開発リスクを少なくするために、存在した面もあると考えてます。
プログラムコードだけでは表せない、システム連係、情報ライフサイル、状態遷移などは積極的に可視化して、エンジニアが見落としていた事実に気付く仕組みを作る事は開発コストが小さくなった今でも有効なのではと思います。可視化された情報より、気付き易さがある資料はありません。

エンジニアがよりよいシステムをつくるためには、暗黙知や知らない業務パターン、ユーザの振る舞いを気付く必要があるのです。初期リリースより、長期運用していくうちにその必要性は増してくると思ってます。システムは大きくなりますし、、人は忘れやすい生き物です。 プロダクトのユーザ価値、暗黙知に埋もれていた状態遷移などに気付く仕組みがあると言うことは品質や技術的負債を未然に防ぐ、開発速度向上、設計力の向上など考えると必要性も高いのではないかと考えます。

優秀なエンジニアは、実はこそっとモデルを書いてる人が多かったりしませんか？ 

# まとめ

優秀者なエンジニアは自分に間違えを気付かせるための手段をもってる！ これが設計書・モデリングだと思います。
指示書としてのドキュメントより、自分が気づくために書くドキュメント、シーケンス図、状態遷移図、クラス図など、すごく簡単なものでもいいので可視化する事によって、 複雑になっていくシステムを品質よく、開発スピードを維持しながら開発していけます。　これは昔もそうだったが、これからも重要な役割だったと改めて気付くにいたりました。


マイクロサービス化や型が見直されている昨今、システム設計もまた見直される時期に来ていると感じざるを得ません。
設計力あげていきたいですね。