なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

仕様書の書き方について

最近ずっと仕様書を書いているのだが、なかなかうまく書けない。できるだけ次はうまく書けるようにメモをしておこう。

設計書の種類と目的

開発工程の共通知識

各設計書の説明に移る前に、ここではウォーターフォール型の開発における開発工程についての概要を記載する。

ウォーターフォール型開発の概要

開発工程についての基本的な説明はwikipediaを参照
ソフトウェア開発工程 - Wikipedia

最もよく知られた従来型の開発工程モデルはウォーターフォール・モデルである。このモデルでは、開発者は上述の工程(局面、フェーズ)を順番に行う。要求仕様を作成し、それを分析し、解決法を設計し、そのためのソフトウェアフレームワークアーキテクチャを作り、コードを書き、評価し(単体テストシステムテストの順)、配備し、保守する。各工程が完了すると、次の工程に進むことができる。ちょうど、家の骨組みを組み上げてから土台を変更できないというのと同じ考え方である。
ウォーターフォール・モデルでは上流工程での間違いや仕様変更を後から訂正・反映することを考慮していないと考えられがちだが、これは誤解である。これは要求管理に変更制御を含めるかどうかという問題である。
この手法は特に大規模なシステム開発や危険の大きいプロジェクト(軍需関係の契約など)で使われている。各工程ごとに契約・入札が行われる場合もある。
大規模なシステム開発ではサブシステム化も併用し、各サブシステムで時期をずらしてウォーターフォール・モデルを採用する事で、先行するサブシステムで発見した問題を後続のサブシステムでは早い段階の工程で取り入れたり、各工程の要員(設計者、プログラマ、テスターなど)や主要イベント(プロジェクト立ち上げ、レビュー、検収、研修、本番稼動など)の平準化を図る場合も多い。また各工程の内部では後述のスパイラルモデルや反復型開発を組み合わせる場合もある。
ウォーターフォールの問題は、要求分析と要求管理についての技術的未熟さから生じることが多い。さらに言えば、開発工程の弱点の把握不足と開発者が問題を理解せずにコーディングを開始してしまうことからも問題が生じる。また、しばしば省略されがちな工程として顧客と開発者の間での共同レビューがある。開発者は危険を承知で設計を進めて開発するが、その設計は最終的には Critical Design Review(最終設計審査)というマイルストーンでチェックを受けることになる。この手法への批判はソフトウェア工学者よりも実際の技術者から出てくることが多い。批判者は WISCY(Why Isn't Someone coding yet ?)アプローチなどを信奉している

ウォーターフォール型開発の標準規格

C++に国際標準があるように、開発工程にも標準がある。工業製品に規格を適用し、業界に標準を取り決めるのは現代社会の一般的な概念である。*1

IPAが出している共通フレーム2007
http://www.ipa.go.jp/files/000005379.pdf
これはISO 12207の標準をもとにIPAでカスタマイズをしたものらしい。汎用的な用語や各工程の内容が規定されている。

共通フレーム2013もあるらしい
IPA 独立行政法人 情報処理推進機構:プレス発表 納品後の利用者ニーズをシステムに適切に反映させるための、新たな役割等を追加した 「共通フレーム2013」を公開

富士通が出してる開発工程標準
標準化への取り組み - Fujitsu Japan
SDEMと呼ばれる

日立が出してる開発工程標準(?)
http://jmn.g-recruit.hitachi.co.jp/job/detail2?URL_KEY=div_it_pm
HIPACEと言うらしい

IBMが出してるやつ
IBM IT構造改革への軌跡―日本IBMの取り組み― プロセス/ツールの整備 - Japan
IGSDF

NECとかはよくわからなかった。あとで調べる。。。

何を述べたいのか、どこについて書きたいのか

とりあえず、工程の定義はそれぞれの会社でなされており、工程ごとに作るものが決まっている(…これを作れば良いという指針はある)。そして、大体ウォーターフォール型の開発だと、下の図のように基本設計と機能設計がある(場合によっては外部設計や内部設計と呼ばれる)。V字モデルってのは、各工程で行った設計を後工程でチェックするというものだ。
f:id:panzer-jagdironscrap1:20140511233042p:plain

参考&画像の取得元:
Vモデル - Wikipedia

ここから先は私の考えが多めに入っているのであんまり信用しないように

基本設計書

基本設計書の目的

・ソフトウェアがどのような機能を持つのか、どのように動かしたいのか、自然言語と図で規定する*2ことでお客さん、開発、営業等の共通認識を得る
・機能設計書と役割上対になる(→機能設計書はどのように実装するのか、基本設計書はどのように動かしたいのか)
システムテストと工程上対になる(→V字モデルから)
・お客さんからの要求が論理的にこの辺までだという線引きのために使われる*3、ここにやると書いてあることはやらなきゃいけない。逆にやらないと書いてあることに責任はない。やらないと書いてあることに対して何かを作れと言われた場合追加発注となる。
・仕様を理解した本人だけではなく、第三者でも基本設計書を読めば納品物(ソフトウェア)を作成できるようにすることが目的の一つにある*4

ひとこと

・最初に設計書を読む対象を定義しその対象であれば理解できるようにすることが必要なように思う(例:開発チーム内部の人には理解できるようにする)。そうでなければタダの怪文書になってしまう。だからお客さん向けの文章をここに書いてしまうのは間違いだし、後工程のテスト方法など書いてしまうのは変*5

・基本設計書についての詳しい記述内容や書き方については後の章に書く

機能設計書

機能設計書の目的

・ソフトウェアにどのような機能を持たせるのか、どのように実装するのか、自然言語と図、UML図、クラス関連図、シーケンス図などで規定することでプロジェクト内の共通認識を得る
・基本設計書と役割上対になる、工程上対になるのは結合テスト
プログラマーに作業を依頼するのはここからということも多い

ひとこと

ソースコードの構造を規定する。これについては特に書くことがないというか、プログラミング言語に対する知識のバックグラウンドがあれば、実装は自ずと見えてくると思う。

詳細設計書

詳細設計書の目的

・ソフトウェアのロジックを、めっちゃ詳細なシーケンス図や処理フローで規定する

ひとこと
  • ネットで検索すると、みんなが批判している。私も作ったことがない。というか時代遅れと言われがちなSIerの私ですら書いたことが無いのに、書かせる企業 is 何。

詳細設計書という名のゴミ | Gm7add9
詳細設計書ってよくわからない - 未来のいつか/hyoshiokの日記
詳細設計書に何を書くべきか? - Sacrificed & Exploited
EXCEL設計書 Vol.1 怪文書大公開 | Rocky Manobi's Blog
詳しすぎる詳細設計書 - SiroKuro Page
設計書の非常識1.設計書には詳細な実装方法を書く - Sacrificed & Exploited
職業PGにわかるFizzBuzz - 日々常々

批判される理由

  1. プログラムとほぼ一対一で対応するようなドキュメントは無駄(…そのようなドキュメントは保守されにくい、プログラマーならばコードを見たほうが早い)。この主張は詳細設計書がゼロでいいとは言っていない、コードと同じようなドキュメントは無駄だという主張
  2. 詳細設計書は、例えば、システム更改後のリグレッションを発見するための指針にはなっても発見には寄与しない。現代ではそれはテストコードを書いて保証すべきことだ(上記を抽象化して説明すると → 詳細設計書はシステムの動作(ビヘイビア)を規定している、しかし現代ではそれはテストコード*6を書いて保証すべきことだ)
  3. 詳細設計書は、仕様通りのソースを書かせるためにソースコードの書き方自体をドキュメントにしている。しかしそれは詳細設計書を書く側の工数、そして詳細設計書を読んで実装する側の工数を浪費する。ソースコードに近すぎる設計書はレビュー時に仕様との付きあわせが出来ずバグを生む


【総括】
ソースコードと一対一になるような設計書を書くことは、設計者と実装者両方の工数を浪費する上に品質を高める効果もない。

理由
以下、「ソースコードに近すぎる設計書」を連呼するが、そのイメージは職業PGにわかるFizzBuzz - 日々常々FizzBuzz設計書に近い

  1. 仕様:ソースコードに近すぎる設計書はレビュー時に仕様との突き合わせが出来ずバグを生むので仕様を指し示す指針に使えない
  2. 労力:ソースコードに近すぎる設計書は作成に労力がかかり品質がそもそも悪い
  3. 実装:ソースコードに近すぎる設計書はメンテナンス出来ずソースコードとの同期もとれないので実装の確認にも使えない
  4. 保守:ソースコードに近すぎる設計書は実装者のコーディングを不自由にする、リファクタリングもしにくくなるのでさらにバグを生む可能性まで生む

対案
だったらどうすべきか?

  1. 仕様:設計書に必要なのは詳細な仕様である、ソフトウェアの振る舞いを決めなければならない。必要なのは、設計書からソースコードが生成できそうなゴミを作ったり、アルゴリズムや制御構文をExcel方眼紙で規定することではない。
  2. 労力:ソフトウェアの振る舞いを細かく規定したいとき、やるべきことはExcel方眼紙づくりではなく詳細なテストコードの作成とテスト自動化である
  3. 実装:実装の確認はソースコードを読むことで十分だ。マネージャ職であれば、詳細設計書を作らせるよりソースを読める人を雇うほうがよほど効率的である。
  4. 保守:詳細設計書という鎖からプログラマーを解き放つことで、アルゴリズムや実装は後から改良できる

設計書作成作業の進め方

基本設計書

基本設計書を作成する上で、大きな要素は2つだ。

① 日本語、書式の問題
 日本語難しいです。馬鹿らしいと思われるかもしれないが、ここを通らなければ仕様のイメージを伝えることができない。

② 仕様検討
 これが肝要。初心者は要求仕様からの引き写しで設計書を作りがちだが…

とりあえず、自分の経験から注意点をまとめた

1.日本語、書式の問題

設計書をどう作成すべき指針について

◇日本語の問題
 ・簡潔に説明する(※無駄な修飾、係り受け、冗長表現を削除する)
 ・文体は統一する(である調)
 ・不明語を作らない、つまり説明のない言葉は使わない、用語を定義する or 前段で説明する*7

◇レイアウト、情報の整理の問題
 ・整理のために表などが必要ならば作成する
 ・他の設計書で実施している項目は積極的に模倣する

 ⇒ 書式の問題が解決されないと、より本質的な仕様検討部分がレビュアーに理解されない
 ⇒ 書式の問題に絞ってレビュアーがダメ出しをして、その内容をメンバーに周知するという方法もある

◇日本語文章上達に関するリンク
 わかりやすい日本語を書くために
 ASCII.jp:エンジニアのための文章上達塾
 http://www.h3.dion.ne.jp/~urutora/bunshoupeji.htm
 SZJ004 設計書の書き方�@〜読み物としての設計書〜: すらすらのブログ
 作文が苦手で困っています。 お勧めの「大人向け文章表現講座」… - 人力検索はてな

◇おすすめ
 技術文書の書き方-テクニカルライティングセミナー わかりやすい技術文書の作成手法
 http://www.yamanouchi-yri2.com/
 これタダで公開してていいんですかね…?

2.仕様検討にあたる部分

◇仕様検討の思考ルーチン
 ①〜③を要求仕様が満たせると判断できるまでぐるぐると回す。

① インプット情報の理解
 顧客からの要求仕様(=インプット情報)は何があるか把握し、更新あれば確認する。
 不明点があれば質問を投げる。インプット情報はいつ更新されるかわからないので
 ある意味ルーチンとしてはイベント的である。

② 機能の動作を脳内で擬似的に考える、エミュレートする 
 機能を実装するためにどのようなモジュールが必要か思考する、
 そしてモジュールの起動、終了、再起動、他のモジュールとの連携、機能の実行時の考慮を行う。
 その際機能がどのように動作するか必要であれば処理フロー図などを書き、思考を整理する。
 整理することで、思考に漏れがあるかどうか判断でき、修正する必要があるかどうかわかる。また、要求仕様を
 満たせるかどうか判断できる。

③ 報連相
 こちらで決めなければいけないことが出たら相談する(⇒連絡 or 課題として提起)。
 これを行わないことはない。仕様誤りを減らす、曖昧なことは絶対許さない。

④ チューイ
・お客様から出た仕様をそのままコピーするのはダメ(…仕様の丸写しはアカン)
・お客様から出た仕様はあくまでやりたいことが書いてあるのみで、それができるかどうかまったく考慮してない。それだけならまだいいのだがお客様自体がやりたいことがわかっていないことがある。更に悪いことに受託開発だと失敗した時の責任もとらないといけない。場合によっては無理ゲーになる。

→ これがうまく回っていないと…?

633 名前:仕様書無しさん[sage] 投稿日:2014/05/08(木) 02:02:20.86 
何度同じ事を繰り返せば生まれ変われるのかな? 
1) 顧客と仕様をそれなりに合意
2) コード何行、設計書何ページと成果量を見積もり
3) 成果量と基準単価から金額と開発期間を見積もり顧客に渋々合意させる
4) 儀式的な設計工程で開発期間を食い潰す
5) 設計書はあるけど設計できていないと社内で薄々気づくが顧客にはONスケジュールと報告
6) 見切り発車でコードを書き始めるが頻繁に設計の相談を行うので遅々として進まず
7) 顧客が遅れに気づき騒ぎ出す
8) 挽回のため追加メンバー投入
9) 一番仕事ができる奴が追加メンバーから質問責めになりオーバーフロー
10) 一番仕事ができる奴が倒れプロジェクト崩壊

設計書が開発に役立った事があるか本気で考えてみよ
http://nozomi.2ch.net/test/read.cgi/prog/1394482348/

蛇足

 ・図も大事だが、処理のメインの説明は日本語で行った方がよい
 ・WEB開発の場合の処理内容と、それ以外の場合だいぶ設計書記述に差がある
 ・WEB開発みたいに作るものが決まっていて社内で経験の蓄積がある場合と新しいものを作る場合は異なることを意識せよ
 ・無理なことは無理と言う、工数がかかりそうならそう伝える

機能設計書

 ・眠いので誰か書いてください

追補編

仕様書の作成は①作業工程の策定、②成果物の策定と密接にかかわっている

① 作業工程の策定とプロジェクトの運営を行うマネージャはまず「人月の神話」を読みましょう

人月の神話【新装版】

人月の神話【新装版】

そもそも何をもって「人月の神話」というのか?これを知らないとシステム開発はピーター・ブリューゲルの絵画の「盲人が盲人を手引きする」みたいになる。↓知識がないまま増員をしてデスマに陥る図。
f:id:panzer-jagdironscrap1:20150411211133j:plain

学べること
・我々が作成するソフトウェア製品とプログラムの違い
・クリティカル・パスとは何か?((→言葉は知っていても実際その知識が必要になったとき対応できない人が多すぎ))
・作業工数見積の際の落とし穴を知る
・etc.etc...

② 成果物の策定については今のところよい書物はない(私の知る範囲でなのであったら教えて)

プロマネのブログの人のエントリが非常に参考になるので引用しておく


詳細設計書も問題だけど、それ以上に成果物定義が問題 - プロマネブログ


問題に合わせてアジャイル、ウォーターフォールを工夫することが肝要だよね - プロマネブログ

まあ、要は本来必要のない成果物を必死こいて下請けに作成させて工数の浪費をするのは馬鹿のやることです。前例は役に立ちますが、前例主義に陥っていませんか?そのドキュメントは本当に必要でしょうか?

③ というかもうウォーターフォール開発やめよう

そういうエントリ
nantonaku-shiawase.hatenablog.com
nantonaku-shiawase.hatenablog.com

*1:工員が作るネジに個人差があってはならない。品質は常に均等であるべきだ。第二次大戦時、一番それが良く出来ていたのがアメリカである。どこの工場の誰が作っても同じ品質のものが出来上がる。一方で日本は三八式歩兵銃をそれぞれの工員がそれぞれの品質で作るのでアレだった。ソフトウェアにしたって、できあがるソフトウェアの差はともかく、工程名に個人差があってはならないよね、という話。

*2:とてもつらい(画像略)

*3:実際にそのような目的で役に立った例は寡聞にして知らないが、無いと困るという話はいっぱい聞くのでやっぱり作らないと困る

*4:GEEK諸兄はこの文章に反感を覚えるかもしれない、しかし設計書にはこのような工業的な思想がバックグラウンドにあると思う

*5:ウォーターフォール型の開発であればテスト方法はこの時点で文書化可能である必要がある、それは新規開発案件の場合無理やと思うし、それこそまずプロトタイプを作っておき、その知識をチーム内に共有しないと不可能だろう。

*6:私は仕事でテストコードを書いたことがない。これは私にテストコードを書く能力がないのと、書く環境にないのが問題だ。テストコードを書くにはテストコードをまず納品物として認めさせ、成功の前例を作って先鞭をつけ、テストコードを書ける人材と評価できる人材を集める必要がある。そう遠くない未来に実現できそうだ。

*7:「ある用語の説明はある用語につながるのだから、不明語を辞書的に解説しても、辞書的な解説を広げるだけではないか!」というような哲学者の方がいると思われるが(…辞書の循環参照問題)。しかし、不明語の問題とは「言葉の意味がわからないからわからん」ではなく「言葉をイメージに繋げられないからわからん」がより本質的だと私は考える。そして、不明語がある or 実装イメージがレビュアーに伝わらない、それは即ちレビュアーが実装可能性を判定できないことにつながる。言葉とイメージでレビュアーの思考を満たすことが、仕様の実装方式を伝えることにつながる早道だ。だから図を多用するんですね。(…蛇足ですがこの辺の理解はラカン哲学のいわゆる「ボロメオの結び目」にヒントがあると思っちゃったりして。)