自己紹介
大阪で 10 年ほど自営業のプログラマーをしています。
独立する前は、特定派遣の会社員でした。
もともとあまりアウトプットをしてきませんでしたが、ここ数年ものすごく困っていることがあり、初投稿をすることにしました。
皆さん普段はどんな設計書を読んでいますか?書いていますか?
SIer の一部界隈では、処理詳細という困った資料が流通しています。
本記事は、この処理詳細がいかに邪魔なのか、どれだけ無駄なのかについて論じたものです。
初めに・サンプル紹介
※サンプルを読まなくても本文を読めるようにしてあります。サンプルは雰囲気を掴むため位にご利用ください。
- 前提
-
このようなアプリケーションを開発着手するというシーン
- デモサーバーは公開停止しました。実際の動作を見てみたい人のためにコンテナで動作できるようにしています。セットアップ手順はこちらです。
- よくある基幹システム開発案件を想定・言語は VB.net, サーバーは ASP.net を利用する
- Code of conduct に記入すべき内容や、オレオレフレームワークについての最低限の解説は別の資料に記載されている
-
このようなアプリケーションを開発着手するというシーン
- データベースの説明
- 設計書 A : ある企業グループ & それに影響を受けた会社が書く設計書
- 設計書 B : 設計書を読む人が本当に欲しい情報
- 設計書 C : 設計書 B の別表現, ポンチ絵を書くのが苦手な人向け
- ソースコード
- この記事での「設計書」について ... 要件定義のすぐ後に作成される設計書を指す。現場により基本設計書と呼ばれたり、この粒度の設計書が一種類だけ存在するケースもある
- 用語「処理詳細」について ... 入力と出力の間を繋ぐ、ロジックの中身に言及している資料
主張 : 処理詳細を書くな
設計書 A に見られる「処理詳細」を書くなというのが、本記事の主張です。
処理詳細のどこがダメなのか?
読む人の邪魔をしている
設計書を読む人が最優先で知りたい情報は、「そのプログラムが何を入力として受け取り、何を出力するのか?」です。
設計書 A は以下のポイントで読む人の負担が大きくなります。
- 入力を表すシート ( 検索シート・画面シート ) と出力を表すシート ( 更新シート・画面シート ) がそれぞれ別・入力~出力を追いかけるときに視線の途切れが発生する
- 入力~出力の間に処理詳細が割って入る・入力~処理詳細, 処理詳細~出力を追いかけるときに視線の途切れが追加で発生する
- 処理詳細自体を把握するために、多くの文字を読む必要がある。「どう入力されたら、どう反応すればいいのか?」が知りたいだけなのに「僕の考えた最強のロジック」の相手をしなければならない
設計書 B は、以下の点に重きを置いています。
- 入力と出力の関係を一つの図で表す
- 入力~出力を追いかけるときの視線移動による負荷を最小限にする
- 入力~出力を把握するための読み込み文字数を最小限にする
人間はミスをします。アクションが 1 つ増えればミスのリスクが 1 つ増えます。視線移動でも文字読み込みでも、ミスのリスクは等しく発生します。
設計書 A は入力~出力を把握するために必要なアクションが多すぎることが問題です。人間がミスをするという当たり前が考慮から漏れているのです。
汚いソースコードと同じ書き方
設計書 A は、入力を記したシート→クドい処理詳細→出力を記したシートという流れで文書が構成されています。
これは「関数の先頭で変数をまとめて宣言→たくさんの変数をつつきまわす長い処理→何十行も経た後、ようやく戻り値が決まる」という汚いソースの代表的な傾向と同じです。
誰かに読んでもらう前提の文書を、可読性ワーストの書き方で用意するべきではありません。
実際汚い
設計書 A の現実として、処理詳細に書いてあるロジック自体が汚いことも看過できません。
今まで見てきた全ての処理詳細は、反吐が出るほど汚いロジックばかりでした。実装者が処理詳細の意味を崩さないよう気を使いながら、適切にメソッドの分割をすることで、何とか体裁を整えているのです。
そのまま実装すれば 1 メソッド 100 行を超えることは日常的にあります。現実に 100 行を超えている下手クソな実装もしょっちゅう見かけます。
循環的複雑度が 70 を超える処理詳細も何度か見たことがあります。処理詳細が世に出た時点で、既に技術的負債となっているのです。
これが現実です。処理詳細でソフトウェアの何かを管理できていると思っている人は、管理できていると思い込んでいるだけです。
業務アプリケーションは簡単な処理しかしません。以下 4 つの要素をそれぞれ別メソッドへ定義するだけで、メンテ性はかなりマシになります。
- 入力のバッファリング
- 入力データの内容チェック
- 入力データを出力形式へ変換
- 出力
たったこれだけです。この業界では「ループしながらバッファリングとチェックを同時に実行する・チェックは入力データの前後関係を気にする・チェックのためにバッファに使うパブリック変数をつつきまわす」という残念な設計をしばしば見かけます。
この程度の腕前で、後工程に役立たずのロジックを押し付けているのが現状です。
未定義の入出力
設計書 A の世界で仕事をしていると、抜け漏れのある設計書を受け取ることがしばしばあります。「こんな入力が来た場合は、どう反応するのが正解か?」が漏れる。処理詳細に夢中になっているうちに、必要な入出力のパターンが漏れるのです。
設計書を書くにも、ソースコードを書くにも、一番最初に整理しておく・一番大事なことが決まっています。「どんな入出力のパターンを網羅すれば正解か?」この当たり前が、設計書 A の世界の住人には分かっていないのです。
抜け漏れが発生するなら、余計な作業はオミットして、自分の本来の役割に専念すべきです。先ずは正常系・異常系両方で入出力のパターンを網羅した資料を作るべきなのです。
当たり前という言葉は、主観的すぎるので本当は使いたくないです。ですが上記の「人間はミスをする」と同様、作業の段取りが稚拙すぎて、当たり前という表現しか出てこない。本当に残念なことです。
処理詳細という不要な情報
新規開発時に処理詳細は不要
実装には入力と出力のペア以外、情報は必要ありません。「こんな処理を書くときは、うちの環境ではこうしてほしい」という事情があれば、それは Code of conduct に書くべきです。
処理詳細が存在する設計書では、どれだけのペアが存在するのか一目見て分かりません。必ず処理詳細を読破しなければなりません。
明らかに不要な作業を強いられる。これは非常に大きなストレスです。しかも処理詳細それ自体が技術的負債です。
後工程の担当者は設計書に対して、高い視点からの俯瞰図を求めています。ですが設計書 A を書く人々は視点が低く、見通しの悪い資料を寄越してくるのです。
なお、低スキル人材がチームにいる場合、どうするか?という問題が残りますが、その人々に処理詳細のみ渡せば、たちまちコードを書けるようになるでしょうか?本当に処理詳細だけで事態は解決するでしょうか?
そんなことはあり得ません。大人しくコピペ元のソースとオレオレフレームワークの解説を渡すべきです。
運用フェーズ・障害対応時に処理詳細は不要
障害対応で必要な情報は以下の 4 つです。
- 入力データ
- 障害発生時のオペレーション
- どんなメッセージが表示されたか
- スタックトレース
入力と出力の関係をおさらいしたいのであれば、設計書を読むこともあり得ますが、それは処理詳細がなくても可能です。
個人の経験として思い返せば、障害対応は一番設計書の出番が少なかったです。多くのケースで入力データとスタックトレースがあれば障害の再現ができるからです。
機能追加・改修時に処理詳細は不要
処理詳細が存在する世界で、プログラムの改修を行う場合、設計書修正フェーズでは検索シート・処理詳細・更新シートで変更部分に赤ペンを入れます。ソースコードがどう変わるのか?がそのまま設計書に書き足されるのです。
新規開発の時と同様で「その結果として、出力がどう変わるのか?」一目見て分かりません。根気よく処理詳細を読む必要があります。たまに赤ペン部分にも未定義があります。設計元に問い合わせなければなりません。
現バージョンはどんな入力を引き受けて、どんな出力をしているのか?スタートラインの情報提示が不十分なまま、赤ペンに従ってソース修正とテストを実施することになります。
問題の根本は新規開発の時と変わりません。後工程に何か情報を引き継ごうとしてはいるのですが、不要な回り道をしているのです。
改修見積もりのために処理詳細が必要という意見があるかもしれません。
実際のところ、処理詳細はデフォルメされたソースコードです。多くの場合、ソースコードは、処理詳細のニュアンスから逸脱しない範囲で、きれいに書き直されています。
処理詳細通りのロジックが実装されていたとして、テストの工数はどうなるのでしょうか?テスト不可の複雑なソースコード改修見積もりを的中させられるでしょうか?
「後々の改修のため」というベンダーだけの都合でお客さんに価格転嫁することはビジネスとして正当なのでしょうか?出来上がる資料は結局のところ役立たずです。正当であるはずがありません。
テストに処理詳細は不要
どんな製品でも、先ずブラックボックステストをクリアしなければなりません。ブラックボックステストの仕様とは、正常系・異常系両方の「どう入力されたら、どう反応すればいいのか?」の集大成です。
つまり、新規開発時・改修時と同じ問題がテスト担当者の前に立ちはだかります。
テスト担当者は処理詳細から出力を予測し、テストケースを作らなければなりません。こうなれば正解という具体的イメージの提示はありません。処理詳細それ自体に間違いが無いのか?は担保されません。
ブラックボックステストを作るために処理詳細を読解しなければなりません。設計の最初の時点で入力と出力のペアが整理されていれば、こんな無駄なことはせずに済むのです。
以前と異なる担当者が改修を引き受けるとしても、現バージョンのテスト資料は決して出てきません。上流工程の仕事は下流工程に処理詳細を渡すこと。彼らはテストの再実行が容易にできるよう環境整備されているか?も気にしていません。
ビジネスオーナーにとって処理詳細は不要
ビジネスオーナーにとって最大の関心事は「そのシステムが業務遂行に足る出力をしてくれるか?」です。
自社システム部門でメンテナンスを行う場合、設計書が必要になるでしょうが、それは処理詳細ではありません。
以前、「処理詳細だけで書かれた設計書」を始末する案件に関わったことがあります。その時お客さん側システム部門の方々は以下のように言っていました。
- この設計書は読んでいない。何か問題があったらソースコードを読んでいる。こんな設計書を読んでもソースコードを読んでいるのと変わらない。
結局、その案件では設計書 C のスタイルで書き直しをしました。
読めない・読まれない設計書を書くことにより、設計工程が 2 倍発生したのです。これはお客さんの時間と金をドブに捨てているのと同じです。
仕事の優先順位を考えているか?
上述の通り、処理詳細が存在すると関係者全員が不幸になります。
こんな役立たずを必死に書くよりも、設計工程では入力と出力の組み合わせに集中すべきではないでしょうか?
入力と出力のペアが列挙されていれば、それをテスト仕様にも利用できます。仕様バグの予防にもつながります。
読み手が欲しい情報を素早く拾い上げることのできる、いい文書を書くことができるようになります。
各工程がクリアすべき事を本気で考えていれば、処理詳細を書く以外の重要なタスクに気づくのではないでしょうか?
余談
どうしても処理詳細を書きたい場合
設計書 C の体裁で書いてください。
先ず入力~出力を一覧にした表現を提供し、それに対する注釈として処理詳細を書きましょう。くれぐれも読む人の邪魔をしないようにしましょう。
処理詳細を読破しなければ、入力~出力までを把握できないなんて無意味な文書は書かないでください。
「処理詳細が不要な人は、処理詳細を読まなくていい。処理詳細を無視したコードを書いていい」と Code of conduct に書きましょう。
デフォルトで処理詳細を書かないようにし、浮いた工数から低スキルメンバーのフォローをする工数 ( 処理詳細を敢えて書くための工数含む ) 及び安全マージンを確保しましょう。
トレーニングの一環としての処理詳細
上流側にいる SIer が、自社人材の育成のために、コーディングの代わりとして処理詳細を書かせるということがあるかもしれません。
しかし、こんなものはトレーニングになりません。「見積もり→設計→実装→テスト→見積もりの振り返り」この 1 セットを何度も繰り返すことが正しいトレーニングです。
自分はこのトレーニングで、それなりのプログラマーになれました。もしも処理詳細を突つくだけのキャリアを積んでいたら、早々に成長が頭打ちになり、ドロップアウトしていたでしょう。
処理詳細が刺さったシーン
何年も前に、実装・テストをオフショアのチームに依頼する案件にて、自分も処理詳細と同じくらい細かい設計書を書いたことがあります。
相手のチームは錬度が低く、送った設計書に対してバグのある ( まれにビルドが通らないことも ) ソースコードを納品してくる状態でした。
設計書送付⇔コードレビューの繰り返しの多さに問題を感じていた自分は、あえて視点の低い・内容が細かい設計書を送ることにしました。
自分が思った通りに実装をしてもらうことと、「こんな処理をしたいときはこうする」という自分のレパートリーを相手に伝えることが目的です。
結果としては、上手く行きました。その時は。
気をよくした自分は、同一オフィスで完結する仕事で、日本人相手に同様の視点の低い設計書を渡しました。
反応は良くありませんでした。
- この設計書の通り実装すれば、多分上手く行くんだろう。けれども、そもそも何をしたいのかが分からない。だから、この設計書が正しいのか間違えているのかも分からない。
その節は大変失礼しました。
処理詳細を書くことが許される人材
- 要件 : 処理詳細を書いている時点で、出来上がったソースコードのコントロールができること。1 メソッド当たり行数は 70 行まで
- SQL はどれだけ長くても 1 行扱い・SQL はそれ自体で単体テストが可能であるため
- 1 画面に収まる範囲として 70 行・本当は 25 ~ 30 行まででコントロールしてほしい
設計書を書く人間も自分で書いていることを忘れます。
忘れた時点で実装・テストから戻ってきたソースコードのレビューが困難になります。
設計書を送付してからソースのレビューまで、短くても数週間かかります。レビュー時点でどんな設計をしたのか思い出さなければなりません。
戻ってきたソースコードがとても汚く長いものだったら、レビューは可能でしょうか?
自分が頼んだ処理がそこに書かれているのか?何よりもその処理の入力と出力はお客さんの業務遂行に足るのか?どうやって担保するのでしょうか?
自分の目で見ても、他人の目で見ても、その処理に正当性があると分かるように、読めるコードを残す必要があるのです。
設計書の時点で品質を担保できないのであれば、無理をしてまで処理詳細を書く理由がありません。
因みに、わざわざ処理詳細を書いている人々のうち、上記要件を満たす人物を自分以外に見たことがありません。
自分も、「ある程度慣れたドメインの業務」「ある程度慣れたデータベース」「( 不幸にも存在する場合は ) それなり以上に慣れたオレオレフレームワーク」という前提条件を満たさないと上記のような真似はできません。
それ位には困難なことなのです。無理して処理詳細を書くべきではありません。仮に書けたところで見返りはありません。
マーケットシェア
体感ですが、大阪周辺の企業の 2 / 3 は「そんなことする必要がない」と判断している状態です。
東芝関連の案件でも処理詳細は書きませんでした。パナソニックに出入りしていた人も処理詳細は書いていませんでした。富士通のイトコでの案件でも処理詳細は書きませんでした。
逆に 1 / 3 の企業は処理詳細を書いてしまっているのです。自分の過去についてあまり触れたくはない・この記事で触れる必要もないのですが、敢えて書きました。
結びになりますが
昨今、いろいろなシーンで「生産性を上げることが重要だ」との主張がなされています。
私たちの業界も人手不足だと言われています。ワークライフバランスに対する要求も高まってきました。こんな世界だからこそ、無駄な仕事は削減しなければなりません。
処理詳細を書くのはもうやめて、より少ない手数でより多い成果を受け取る仕事をしましょう。
Special thanks
デモアプリのコンテナセットアップ手順・Google maps API キー取得は以下の記事を参考にしています。
Google Mapのキーの取得方法
追記 2024/10/19 責任の分解について
発端は以下のポスト・一週間くらい考えた結果を以下に追記します。
https://x.com/izutorishima/status/1844147311427060037
厳しいお客さん相手には、設計書をこんな感じで書かざるを得ないとのこと。
ミスがあったときに、どこでだれが問題を起こしたのか分かるようにするため。恥ずかしながら観点から漏れていました。
https://x.com/p_ros_we/status/1844185718828171427
https://x.com/hgprDragon/status/1844170231587143822
恐らくこんな状況なのだろうと認識しました。
こういう客に捕まったのは本当に同情を禁じ得ませんが、
責任の分解において処理詳細 ( 詳細設計書 ) を持ち出す必要はない
- 図が上下に分かれているのは「一次下請けまでで完結」するか「二次下請け以降にも仕事を依頼する」かだけの差です。図を起こした後に気づきましたが、大して意味はありません
本記事で繰り返し主張している通り、本来求められているのは、そのソフトウェアがどんな入力を受け取り、どんな出力をしたのか?です。
関係各社で役割を全うしていれば、処理詳細 ( 詳細設計書 ) なんて面倒なものをつつきまわす必要はないのです。
なお、自分が見てきた例は以下のような状況でした
処理詳細が紛れ込む理由は、自分の役割を全うできなかったエクスキューズなのか...
他人の頭の中についてアレコレ考えても所詮、下衆の勘繰りなので無駄です。
設計書の書き方云々よりもヤバいものが見えていますが、もう何も言いません。
下流工程がどうしても信用できない場合
https://x.com/DevenMive/status/1844332685575201196
自分も、ある程度は同意します。スキル水準の低い人材がチームに存在する状況が回避困難なのは確かです。
どうしても実装が信用できないのであれば、例えば以下の仕組みを用意してはいかがでしょうか?
- Code of conduct 別冊・コードレシピを用意する
- 「こんな処理を実装したい場合はこれ」という鉄板実装パターンが書かれている
- よりエレガントな実装を提示した者が後勝ち更新する
- 更新にはチームメンバーの査読・メンバー間の合意が必要
- 設計書にも「この部分はコードレシピの xxx を利用してください」と記入できる
- コードレビュー時に「コードレシピに従っていないから却下」は許容されない。従っていない = よりエレガントな実装の提示であるとしてコードの査読をすること
- スキル水準の低いメンバーが態々コードレシピの更新に挑戦するとは考えにくいため
- コードレビュー時に「コードレシピに従っていないから却下」は許容されない。従っていない = よりエレガントな実装の提示であるとしてコードの査読をすること
- コードの実例を設計書に書かなくて済む
- 設計書の可読性が上がる
- 設計書ごとに重複する内容を書かなくて済む
- 入出力のパターンのレビューに集中できる