いものやま。

雑多な知識の寄せ集め

ソフト開発における「設計」とは何なのか。(その9)

前回はユースケース記述について書いた。

今回は設計書に書いた方がいいことについて。

設計書に書くといいこと

実際のところ、設計書に何を書いたらいいのかを画一的に述べるのは、かなり難しい。 というのも、ソフト開発における「設計」とは何なのか。(その5) - いものやま。にも書いたとおり、設計書というのはコミュニケーションのためのツールにすぎないので、十分なコミュニケーションを取れるかどうかで書く内容や量も変わってきてしまうから。 あるチームだと本当に簡潔な内容で済むかもしれないし、別のチームだと綿密に書く必要があるかもしれない。 開発の領域によっても書くべき内容は変わってくるしね。

ただ、とはいっても原則的なところはあるので、その原則を抑えたうえでチーム内でテーラリングしていけるといいんじゃないかと思う。

  • 概要から始め詳細へ分解する
  • 境界に注目する
  • 検討内容と選択理由を書く
  • ファイル一覧を書く
  • 影響範囲を書く
  • テスト設計する

概要から始め詳細へ分解する

設計書の大きな目的は、やろうとしている変更の方向性がちゃんとあってるかを確認すること。 なので、大きな方向性がまず間違ってないかを確認し、それをさらに小さく分解して、それぞれの方向性が間違ってないかを確認していくといい。

たとえば、まずシステム全体の構成を考えて、各モジュールの役割を考えて、その中でどういったクラスを用意するかを考えて、さらにはデータ構造はどうするのか、メソッドはどうするのか、どんなアルゴリズムを使うのかと、詳細へと落とし込んでいく。

もちろんこれは、開発の段階や内容、そして開発するエンジニアのレベル感によって、どこを書くのか、どこまで書くのかは変わってくる。

たとえば、一番最初の開発ならシステム全体のアーキテクチャから考え始めないといけないわけだけど、その後の開発なら全体像はもう決まっているので、今回開発する部分にだけ絞って記述すればいいとなる。 あるいは、ライブラリ開発だとシステム全体のことは気にしないでライブラリ内の構成だけ考えればいいし、逆にマイクロサービスを組み合わせて大きなサービスを作り上げるとかだと全体の構成や他のサービスへの影響とかも考える必要が出てくる。 あと、シニアなエンジニアなら設計では概要レベルだけ書いておけばあとはお任せでOKとなるけど、ジュニアなエンジニアに任せる場合は設計段階でより詳細まで詰めておいた方が安心できる。

このあたりの調整は必要。

で、その調整をしやすくする意味でも、設計書も何回かに分けて途中で確認しながら書いていくといいところはある。

まずは書こうと思っていることの目次だけ用意してチェック。 次に概要レベルの部分を書いてチェック。 それもOKならそれより少し詳細に入ったところまで書いてチェック。 みたいのを繰り返しながら、もうあとは大丈夫かなというところで設計書は完成にして、その方針にしたがって実装するみたいな。

境界に注目する

上記とも少し関係するところだけど、システムというのは完全な一枚岩でできているわけではなく、いくつかの部品が組み合わさってできあがっている。 で、部品内の作りはいくらでも変えられるんだけど、部品と部品をつなぐ部分、つまり境界については、簡単に変えることができない。 なぜなら、そこを変えると両方の部品に変更が入ってしまうから。 なので、部品と部品の境界、すなわちインタフェースについては、しっかりと考えた方がいい。

なので、まずシステムのどこに境界があるのかをちゃんと把握するといい。 そして、その境界のインタフェースをしっかりと定める。

さらにいうと、部品は普通入れ子構造になっていて、部品の中にはさらに小さな部品が集まっていたりするはず。 なので、必要なところまでブレークダウンしていく必要がある。

たとえば、フロントエンドとバックエンドが協調して動くなら、まずそこに境界があり、インタフェースが存在することになる。 これは普通はWebAPIとして規定されるはず。 さらにはバックエンドの中にも複数の層があったりして、そうなるとその間にも境界があり、やはりインタフェースを規定することになる。 その各層にも複数のモジュールが含まれていたり、さらには複数のクラスがあったり、みたいな。

これもどこまで掘っていくかというのはあるんだけど、そうやって境界を意識することで、かっちりと決めておかないといけない部分が見えてくると思う。

検討内容と選択理由を書く

設計というのは「How」すなわち「どうやるのか」の取捨選択だということを書いた。 なので、要件定義書と同じように、「なんでその選択をしたのか」というのを書いておくといい。

とくに「この方法ではやらない」というのを書いておくといい。 理由についてはこれも要件定義書と同じで、選ばれなかった方法についてはソースコードに何も情報が残らないから。

ファイル一覧を書く

そんな感じで検討しながら詳細に詰めていくわけだけど、ついでにこれを書いておくといいかなというのがファイル一覧。 今回の開発で、このファイルが新規に増える、このファイルに変更が入る、このファイルは削除する、というのをツリーで書いておくイメージ。

- project_dir/
  - hoge/
    - hoge.py  # 新規;XXクラスを実装
    - huga.py  # 変更;XXクラスに対応、piyo.pyと統合
  - (piyo.py)  # 削除 -> huga.pyへ統合
  - ...

みたいな。

これを書いておくと以下のようないいことがある:

  • どのあたりに変更が入るか分かりやすい
    • 変更する場所や内容が適切かがこれでけっこう分かる
  • 新規ファイルの場所や名前を適切にしやすい
    • バージョン管理でファイルの位置や名前が変わると変更を追跡しづらくなるので、作ってしまってから変えるのではなく、あらかじめ合意をとっておいた方がいい
  • 変更の影響が分かりやすい
    • 意外なところにも変更が入ると気づけると、影響範囲の推測でミスしづらくなる

ちなみに、ファイル全部を書くのは大変なので、今回の開発に注目したところだけ書くのでOK。 書く量が多すぎるならディレクトリレベルで「このディレクトリ以下に変更が入る」とかでもいい。 まぁ、書く量が多すぎるとしたら、ちょっと設計として問題ありなのかもみたいな嗅覚も働かせたいところだけど。

影響範囲を書く

開発で怖いのはデグレ。 なので、今回の変更でどこら辺のコードにも影響が発生するのかは書いておいた方がいい。 これを複数人でレビューしておくことで、影響範囲の考慮漏れがないかとかを考えられる。

このときに注意したいのは、影響を受けるのはコードだけじゃなくて、ドキュメントやテストもあるということ。 今回の開発によって新たにドキュメントを作る必要が出てくるとか、ドキュメントのここの記載が変わってくるとか、今まで通ってたこのテストが通らなくなるとか。

そのあたりを抑えられてないと、あとになってドキュメントの記載が間違ってるという話がきたり、テストが急に通らなくなったんだけどとかが出やすい。

ちなみに、ドキュメントやテストのソースもあるなら、上記のファイル一覧を書くときにそれらに対しても「このファイルに変更が入る」と書いておくことになる。 そういった意味でもファイル一覧を書いておくのは影響範囲の考慮漏れを防ぐのによかったり。

テスト設計する

あとはテスト設計も書いておくと安心なところがある。 もちろん、厳密に書くと大変なので、基本的には「こんな感じのテストをしようと考えてる」くらいでOKだけど。

ただ、データの境界値とかが明確に決まっているのなら、その仕様についても書いておくといいかも。 あとでテストレビューをするときに、境界値に対してちゃんとチェックできてるかが確認しやすいので。


以上が抑えられていれば、コードが出来上がってきてから「思ってたのと違った」となるリスクをだいぶ抑えられると思う。 かつ、設計書自体のボリュームもそれなりに抑えられるかなと。

今日はここまで!