はじめに
DIGGLEエンジニアのaki0344です。
去年から専任のスクラムマスターとして活動しています。
最近設計について思うところがあり、記録の意味も込めてブログにしてみました。
なぜ設計をするのか?
みなさん設計していますか?
1つのプロダクトを2~3人程度で開発しているような環境では、明確に設計という工程を設けずにいきなり実装を行っているかもしれません。
あるいは、納期に対して開発機能が極端に多い場合、設計作業は後回しにされ、とにかく動くものを作るということが優先されてしまうかもしれません。
設計をしなくてもコードを書けば動くものは作れるため、ときに軽視されてしまうこともある設計ですが、以下のようにメリットがあるため設計はなるべく行ったほうがいいと私は思います。
情報の共有
システム開発には多様な立場の人が関わります。
ソースコードはシステム開発に携わる人々の共通言語ではありません。
PdMはエンジニア出身である必要はありませんし、プロダクトに参画したばかりのエンジニアはソースコードを見ても「なぜそうなっているのか」はわかりません。
設計を行い、設計書を残すことはそうした多様な立場の人々の間で認識を共有するのに役立ちます。
なぜそうなっているのか、想定しているアウトプットに齟齬がないか、すでにプロジェクトから離れた人がどのような仕組みを考えていたのか……。
設計書があることで、時間や立場を超えて多くの人々が同じ情報を獲得することが可能となります。
作業の分離
もう1つの大きなメリットとして、作業を切り分けることができるという点があると思います。
人間の脳はマルチタスクには向いていないという研究結果は様々な場所で報告されています。
設計を省略していきなり実装を行っているときには意識しないかもしれませんが、実際には要求された機能を満たすロジックを考える行為と、それを実現するためのコードに落とし込むという行為は大きく異なる思考を行っているはずです。
この2つの思考を同時に行うことで不完全な、あるいは非効率なロジックが生まれやすくなったり、作業効率が落ちるといった事態を招く可能性が高くなります。
設計を行うと工程が1つ増えるため一見非効率に思えるかもしれませんが、不完全なコードにより発生する後戻りや保守性の劣化を考慮すると、設計と実装は分けて行ったほうがいいと思います。
開発手法と設計の位置づけ
さて、どんな設計を行い、どのような設計書を書くかはプロジェクトによって異なると思います。
どこまで詳細に書くか、どのようなフォーマットで書くか、何を目的として書くのか……。
私は最近、開発手法によって主眼となる目的が変わってくるのではないかと考えるようになりました。
ウォーターフォールの設計
私は社会人経験の大半をメーカーからの受託開発を行うSIerとして過ごしてきたため、ウォーターフォール開発が私にとってもっとも馴染み深い開発手法となっています*1。
これは日本のSIerの契約形態によるところも大きいのですが、ウォーターフォール開発では多くのプロジェクトが3か月を1つの単位として開発を進めているかと思います。
小さい改修だと3か月、大きいプロジェクトだと6か月や1年など、3か月×N回のような区切りで要件定義~受け入れテストまで一連の流れを1回まわすようなイメージです。
設計書の構成
数人~数十人で3か月×N回の期間開発を行うため、必然的にやるべきことは多くなります。
十数ページから数十ページの要件定義書から数十ページから百数十ページの基本設計書を作り、数百ページに及ぶ機能設計書を書き、もはやどこからどこまでを1ページと換算すればいいかわからない詳細設計書を書く……。
ウォーターフォール開発を経験されていれば、このような開発に1度は出会ったことがあるのではないかと思います。
何を主眼とすべきか
膨大な構成となりがちなウォーターフォール開発の設計でもっとも重要なことはなんでしょうか?
人によって意見がわかれるかもしれませんが、私は「前工程で定義された内容が漏れなく設計書に記載されているか」だと考えています。
ウォーターフォール開発で実装する際に参照されるのは、最後に作成された設計書です。
したがって、そこに記載されていない仕様は実装されないことになります。
このミスが発覚するのは結合テストや総合テストと言われる、実装後のテストより後の工程になってしまうため、開発期間の終盤に規模や工程の大きな追加対応を迫られることになります。
私が過去に所属していた組織でも、このようなバグが出ると原因分析や水平展開調査、再発防止策の策定など、バグの修正だけではなく追加の対応が必要となっており、とにかく前工程からの漏れを嫌う文化が根付いていました。
スクラムの設計
DIGGLEではスクラムによる開発を採用しています。
スクラムを含むアジャイル開発では、ウォーターフォール開発のような壮大な設計書を作成しているプロジェクトは少ないのではないかと思います。
工程もウォーターフォールのように基本設計、機能設計、詳細設計と明確に複数には分かれておらず、「要件定義が出てきた後に実装するために情報を整理する期間」のように1つしか存在しない、あるいは最初は必要最小限の記載のみにとどめておき、実装と並行して肉付けしていくのが一般的ではないかと思います。
DIGGLEでもウォーターフォール開発に比べると設計書は圧倒的に少なく、設計工程も1つしか存在しません。
設計書の構成
スクラムではユーザーストーリーを起点に開発が進みます。
ユーザーストーリーごとに機能を実装し、リリースが行われます。
必要な機能はそれほど複雑なものではないため、1回のリリースは規模の小さいものになります*2。
実装する機能は小さく、影響範囲も限定されているため、プロダクト全体を見渡す必要性はそれほどありません。
限定された範囲を確認すればよく、実装を直接確認すればいいという場合も多々あります。
また、ユーザーストーリー単位で開発を行うため、後から見返したときに全体の構成を見るよりもユーザーストーリー単位で経緯を追えたほうがメリットが大きくなります。
そのため、スクラムで開発を進めているチームは、設計書をユーザーストーリー単位で作成しているところが多いのではないかと思います。
DIGGLEでも設計のアウトプットは主にユーザーストーリーから作成されたタスクに記載されています。
タスクはユーザーストーリーやPull Requestに紐づけられているため、後から見返したときに容易に追うことが可能となっています。
何を主眼とすべきか
スクラムの強みはチームでものごとに取り組む点にあります。
スプリントという短い期間の中で、設定したゴールに向けて開発を進めていきます。
ここで重要なのは、いかに全員が同時に動ける状態を作るかです。
たとえ「今スプリントではある機能Aを作ろう」と決めてどんなに詳細な設計をしても、実装が順番にしか進められない状態だと1人分の力しか発揮できません。
複数人で同時に作業を進められる状態にして初めてスクラムの本来の力を発揮することができます。
並列で実装を進めることでより早く市場に新しい機能を届け、より早くユーザからのフィードバックを受けて改善ができるようになるのです。
したがって、スクラムでの設計でもっとも重視すべきなのは「タスクの並列実行性」です。
ユーザーストーリーを小さな作業単位に分解する際、タスク間の依存関係を最小限に抑えることで、チームメンバーが同時に作業に取り組める環境を整備することが可能になります。
まとめ
システム開発について検索すると設計という工程を解説しているページは無数に出てきますが、開発手法ごとにどう設計するかという解説は見当たらなかったためブログを書いてみました。
今回ブログを書きながらあらためて考えてみると、設計書をどのような形式で書くのかというのはチームのあり方に影響を与える可能性があるのではないかという思いも強くなりました。
今回私が書いたのは、あくまで私の中で「こうではないだろうか」という主観になります。
設計書の書き方に正解はなく、プロジェクトによって答えが違っていていいものだと思います。
まだ設計書のフォーマットが固まっていないプロジェクトに関わっている方は、どのようなチームを目指すのかイメージしながら設計書のフォーマットを考えてみるといいかもしれません。
終わりに
DIGGLEではともにプロダクトを開発してくれるエンジニアを大募集中です。
少しでも興味があれば、ぜひ下記採用サイトからエントリーください。
カジュアル面談も実施しているので、気軽なお気持ちでご応募いただければと思います!