詳細設計の必要性について改めて考えてみる

この記事は「ネオシステム Advent Calendar 2023」の25日目の記事です。

# はじめに
<img width="300" alt="af315790-1a1b-449a-9cfc-6168728b4c3e.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252524/7268a987-8b65-8783-3ad3-82da195b156e.jpeg"><img width="300" alt="932f219a-78e3-473a-93aa-6ebeedd45a2f.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252524/54390699-7d9b-7fc8-53b8-448400e7248c.jpeg">

皆さん、今日も楽しく詳細設計と向き合っていますでしょうか。

「詳細設計」という言葉自体とても鵺的な印象です。
そのためか現場やそれに携わる人によって捉え方が違うだけでなく、そもそも行う必要が無いと言い切る人もいるぐらいです。

直近で携わったプロジェクトでも正にそのような場面に直面する機会がありました。
そのため、今回は自分の詳細設計に対する思いをまとめてみるべく、ポエム的な感じで記事を書いてみたいと思います。

で、冒頭の画像は例の如く生成AIに作成してもらった「詳細設計書」の画像です。
とても「詳細感」はあるのですが、何を書いているのか全くもって分からないですね…
生成AIからしてもやはり詳細設計書は鵺的なものなのでしょうか:thinking:

# 前提
* 本記事は、独断と偏見を多分に含んだポエム感強めな記事です
* ここでの詳細設計は、一般的なプログラム開発で求められる詳細設計です

# 詳細設計とは
[ネット上で検索](https://www.google.com/search?q=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA+%E8%A9%B3%E7%B4%B0%E8%A8%AD%E8%A8%88&rlz=1C1JCYX_jaJP1070JP1070&oq=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA%E3%80%80%E8%A9%B3%E7%B4%B0%E8%A8%AD%E8%A8%88&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBCTE1NjE2ajBqMagCALACAA&sourceid=chrome&ie=UTF-8)してみると、以下のような記載が多く見受けられました。

* システムの内部構造等の専門的な内容を設計する工程
* システムに必要な機能を実装する工程
* プログラミングによる開発ができるようにシステムの内部構造を検討する工程
* 基本設計で決められたシステムの動作をどのように実現するかを示す工程

詳細設計の趣旨としては間違っていない印象ですが、具体的に何を作成すれば良いかが曖昧な印象です。

記事の中には具体的に「プログラムや対向するシステム（DB含む）との関係や遷移を定義」と書かれているものもあったのですが、個人的にそれは基本設計で定義することが多いです。

詳細設計が不要と言われる現場では<b><font color="red">「基本設計との住み分けができていない」</font></b>ことが多い印象です。
住み分けできていないから「書かなくてよい」「基本設計に書けば良い」になるのも分からなくは無いのですが、各設計が誰のためのものかを意識できれば、何を書くべきかも分かりやすくなり、住み分けもしやすくなるかと考えます。

# 基本設計と詳細設計は誰のためのものか
基本設計は「お客様向け」、詳細設計は「プログラマ向け」だと認識しています。
[ネット上で検索](https://www.google.com/search?q=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA+%E8%A9%B3%E7%B4%B0%E8%A8%AD%E8%A8%88+%E8%AA%B0%E3%81%AE%E3%81%9F%E3%82%81&rlz=1C1JCYX_jaJP1070JP1070&oq=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA%E3%80%80%E8%A9%B3%E7%B4%B0%E8%A8%AD%E8%A8%88%E3%80%80%E8%AA%B0%E3%81%AE%E3%81%9F%E3%82%81&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBCDkzMjFqMGoxqAIAsAIA&sourceid=chrome&ie=UTF-8)しても、概ね同じ内容でした。

# 基本設計と詳細設計には何を書くべきか
### 基本設計
<b><font color="green">「お客様が実際にできあがるシステムを把握するために必要な情報」</font></b>を記載するようにしています。具体的には主に以下の情報です。

* 機能一覧（機能概要を含む）
* インターフェース仕様（Webアプリなら画面設計書、WebAPIならAPI設計書）
* データベース定義
* システム構成図

システムがどのような機能を有していて、どのような情報を入出力とするのか。
入出力するデータをどこに、どのように格納するのか。
機能とデータベースがどのように関連するのか。
機能要件の範疇で言えば、お客様が気にされるポイントはこれらが多いと考えています。

### 詳細設計
<b><font color="green">「プログラマがプログラムを実装するために必要な情報」</font></b>を記載するようにしています。基本設計の機能一覧の各機能に対して以下を書くようにしています。

* 処理フロー
* 必須ライブラリ
* 規約（コーディングルール、ライブラリやフレームワークの使用ルール）

あまり細かく制限してしまうと、後の実装工程が「詳細設計の写経をするための工程」になってしまうので、そうならないようにプログラマが適度に実装を楽しめるように配慮することを心掛けています。

ただ、あまり好き勝手に実装されてしまうと方針がずれてバグや後の保守工数増に繋がってしまうため、守ってほしい点は規約で制限しています。

このように誰のための設計なのかを意識すると書く内容も異なるので、住み分けもしやすくなるはずです。
ただ、それでも詳細設計を行わない現場も少なからずある認識です。

# それでも詳細設計を行わない理由
[ネット上で検索](https://www.google.com/search?q=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA+%E8%A9%B3%E7%B4%B0%E8%A8%AD%E8%A8%88+%E4%B8%8D%E8%A6%81&rlz=1C1JCYX_jaJP1070JP1070&oq=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E9%96%8B%E7%99%BA%E3%80%80%E8%A9%B3%E7%B4%B0%E8%A8%AD%E8%A8%88%E3%80%80%E4%B8%8D%E8%A6%81&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBCTEyNDIwajBqMagCALACAA&sourceid=chrome&ie=UTF-8)してみたところ、以下のような理由が多いようです。
私が見てきた現場でも同じような理由が大半を占めていました。

1. メンテナンスが大変
1. 工数削減

### 1. メンテナンスが大変
正直私も困ることが多く、最適なアプローチも未だに見出せていません。
そのため、これを盾にされたら黙ってしまうと思います…
どうしても緊急対応等で「即プログラムを修正して即リリース！」と迫られる場面もあり、そういった際にプログラムとの乖離が生まれ、メンテナンスがし辛くなる印象です。

かつて「PlantUML」を利用してテキストベースで詳細設計を作成することで、プログラム改修と合わせて設計も修正しやすくなるのではと思った時期もありました。
ただ、PlantUMLの記法に癖があるためか慣れるのに割と手間取る方も多く、結局頓挫してしまいました。

### 2. 工数削減
確かに工程そのものを省けば工数削減に繋がるかと思います。
ただ、先述した通り「規約」が疎かな状態で実装を行うと、どうしてもプログラマの主観で実装が進みます。それがバグや後の保守工数増に繋がり、結果として「工数増」に繋がりかねません。

# 詳細設計を行わないことによるデメリット
工数削減が図れたとしても、当然それに伴うデメリットもあります。
個人的には以下がデメリットであると考えています。

### 1. ウォーターフォール型開発に合わない
日本の開発現場は、良くも悪くも「ウォーターフォール型」に準拠して開発を行う現場がまだまだ多い印象です。
その場合、詳細設計工程での成果物を評価・承認し、後工程である実装に進みます。
成果物が無ければ後工程に進むことはできないため、当然そのような現場では詳細設計を行う必要があります。

### 2. コードレビューがし辛い
レビュー観点は様々ありますが「仕様通りか」はどの現場でも確認しているかと思います。
仕様通りに実装されているかを確認する際、引き合いにするのは詳細設計書です。

また、レビューアは得てして忙しい人（色々な知見を持っていて責任のある人）が選ばれやすいと思います。ただでさえ忙しいのに仕様を把握する術が無いままレビューを依頼されるのは中々に酷です。

# それなら必ず作った方が良いのか
「必ず」と言い切れないのが辛いところです。。

先述した通り、詳細設計はどうしてもシステムの稼働期間が長引けば長引くほどメンテナンスがし辛くなります。稼働期間が長引けば普通ならシステムの保守体制も減少していきますし、よりメンテナンスに掛ける工数が割けなくなります。
そんな状況で精緻なメンテナンスを続けることは非常に厳しいです。

落としどころとしては「初期開発時は必ず作成」し、「リリース後は多少疎かにしても構わない」というところでは無いかと考えます。

# 最後に
結局明確な答えに辿り着くことができませんでした:sweat_smile:

必要かどうかはやはり現場や体制、お客様の思い等色々なものに左右されがちな印象です。
それらを踏まえてなお、不要だと判断できるのなら作成しなくても良いと思います。

ただ、システムやそれに纏わる人たちの移り変わりは激しく、ずっと不要だと判断し続けることも困難です。不要なものを後から必要なので作るとするのも大変な労力が掛かります。

それらを踏まえるとやはり「作った方が良い」のではないでしょうか。

# Advent Calendarをやり終えて
今年の Advent Calendar も今日がいよいよ最後の日となりました。
業務等で忙しいにも関わらず、快くこの取り組みに賛同して寄稿して下さった皆さんには本当に感謝です。

「今年こそは！」「業務が…」の無限ループに陥っていましたが、今年はようやく一歩踏み出すことができました。そして想像以上に色々な気付きも得ることができました。

今思えば多少無理してでも早く手を出すべきだったなーと感じています。
私に踏み出す勇気を与えて下さった前現場のYさんにも本当に感謝です。

最後に改めて、今回の Advent Calendar に協力して下さった皆さん、
本当にありがとうございました。