設計
要求を満たすソフトウェアの構造や振る舞いを、実装前に決める活動
設計とは
ソフトウェアにおける設計とは、要求を満たすためにシステムの構造・モジュール分割・データの流れ・振る舞いを、実装に着手する前に決める活動だ。何をどう作るかの見取り図を描く工程であり、設計の良し悪しがその後の開発速度・保守性・拡張性を大きく左右する。
設計のレベル
設計は粒度によって段階に分かれる。
| レベル | 決めること |
|---|---|
| アーキテクチャ設計 | システム全体の構成、技術選定 |
| 詳細設計 | モジュールやクラスの責務、インターフェース |
| データ設計 | テーブル構造、データの整合性 |
下位の設計は上位の決定を前提に組まれるため、上位を覆すと下位が連鎖的に作り直しになる。データストアを RDB から分散 KVS へ変えれば、テーブル設計もそれを触るクラスも書き直しになる。だからといって最初に全部を決め切れるわけではない。先に固めるべきは「変更コストの高い決定」だけで、それ以外は作りながら決めた方が精度が上がる。
良い設計の原則
良い設計は「変更に強い」ことを目指す。責務を一つに絞る単一責任、関連の薄い部分を切り離す疎結合、内部実装を隠す情報隠蔽といった原則は、いずれも「変更の影響範囲を局所化する」という同じ目的に向かっている。
原則の出自を辿ると、この目的がはっきりする。情報隠蔽は David Parnas が 1972 年の論文「On the Criteria To Be Used in Decomposing Systems into Modules」で示した考え方で、モジュールの分け方は処理の手順ではなく「変わりやすい決定をどこに閉じ込めるか」で決めよと論じた。結合度と凝集度は Larry Constantine が導入した尺度で、単一責任の原則はそれらを Robert C. Martin が 1990 年代後半に 1 つの原則として束ね直したものだ。
機序は単純だ。結合が強い、つまりモジュールが相手の内部構造やデータ形式まで知っていると、相手を変えた瞬間に呼び出し側も直す必要が出る。逆に凝集が低い、つまり無関係な処理が 1 つのモジュールに同居していると、そのモジュールは互いに無関係な複数の理由で変更を受け続ける。要求は必ず変わるという前提に立つと、変更の入口を絞るこれらの原則の価値が見えてくる。
アーキテクチャとの違い
「設計」と「アーキテクチャ」はしばしば同義に使われるが、区別すると議論が整理しやすい。アーキテクチャは後から変えにくい大局的な決定 (システム分割、通信方式、データストアの選定など) を指し、設計はその枠内での構造化 (クラスの切り方、関数の分け方、命名) まで含む広い言葉だ。「アーキテクチャは設計の一部で、特に変更コストが高いもの」という整理をしておくと、どの決定にどれだけ時間をかけるべきかの目安になる。逆に言えば、後から安く変えられる決定を会議で長時間議論するのは設計工数の誤配分である。
実務での進め方
実務の設計は文書と対話で進む。データの流れを図にする、テーブル構造を ER 図に起こす、処理の順序をシーケンス図で確認するといった可視化は、頭の中の構想の矛盾を早期に炙り出す。またチーム開発では設計レビューが品質の要で、実装前にモジュール分割や責務の置き方について他者の目を通すことで、手戻りの大きい誤りを安く発見できる。重要な決定については「なぜその選択をしたか」を記録に残すと、後任者が経緯を辿れる資産になる。
過剰設計という落とし穴
将来を見越して柔軟性を盛り込みすぎると、使われない抽象化が複雑さだけを増やす過剰設計に陥る。必要になるまで作り込まない (YAGNI) 姿勢と、シンプルさを優先する判断が、現実には堅牢な設計につながることが多い。設計は「正解を一度で当てる」よりも、変更しやすく保ち続ける営みだと捉えたい。ここでの判断力は原則の暗記からは生まれず、変更要求で痛い目を見た経験と、他人の設計を読む量に比例して育つ。
理解を深めるには関連書籍が参考になる。
この記事は役に立ちましたか?
関連用語
クリーンアーキテクチャ
ビジネスロジックを外部の技術的詳細から分離し、依存関係を内側に向けることで変更に強い設計を実現するアーキテクチャ原則
SOLID 原則
オブジェクト指向設計の 5 つの基本原則で、保守性と拡張性の高いコードを実現する
結合度
モジュール間の依存の強さを示す設計指標で、低いほど保守性が高い
リファクタリング
外部の振る舞いを変えずにコードの内部構造を改善し、保守性と可読性を向上させる手法
YAGNI
You Aren't Gonna Need It - 今必要でない機能を先回りして実装しない原則
オニオンアーキテクチャ
ドメインロジックを中心に据え、外側の層が内側に依存する同心円状のアーキテクチャ