設計のフレームワークを作っていたら、モデリングのフレームワークになっていた

現在、私はソフトウェア開発における「モデリングのフレームワーク」を作っています。

もともとは、より良い設計をするためのフレームワークを作ろうとしていました。

しかし、考えているうちに、あることに気が付きました。

要件定義、仕様策定、設計、そして実装は、それぞれ独立した活動ではなく、前工程で作られたものを、別の形でモデリングし直していく活動なのではないか。

この気付きから、現在は「設計のフレームワーク」ではなく、「モデリングのフレームワーク」として整理し直しています。

要件定義、仕様策定、設計、実装は、すべてモデリングなのではないか

ソフトウェア開発では、一般的に、

要件定義
  ↓
仕様策定
  ↓
設計
  ↓
実装

という工程に分けて考えます。

以前の私は、これらをそれぞれ別の作業として捉えていました。

しかし、モデリングという視点から見ると、少し違った見え方をします。

例えば、要件定義では、現実世界の課題や目的を、「システムが何を達成する必要があるのか」という形に変換します。

仕様策定では、その要件を、「システムがどのように振る舞うべきか」という形に変換します。

設計では、その振る舞いを、「ソフトウェアをどのような構造にすれば実現できるか」という形に変換します。

そして実装では、その設計をコードという形に変換します。

つまり、

現実の課題・目的
      ↓
要件として表現
      ↓
仕様として表現
      ↓
設計として表現
      ↓
コードとして表現

というように、同じ対象を、工程ごとに異なるモデルとして表現していると考えることができます。

この見方をすると、要件定義、仕様策定、設計、実装の間にあった境界が、少し違って見えてきました。

モデリングのフレームワーク

現在作っているフレームワークは、まだ大枠しか定まっていません。

イメージとしては、クリーンアーキテクチャのような同心円状の構造を考えています。

中心から外側に向かって、上流工程から下流工程へと進んでいきます。

そして、それぞれのレイヤーには、その工程で適切なモデリングを行うための考え方を配置します。

             ┌───────────────────┐
             │      実装          │
             │ ┌───────────────┐ │
             │ │     設計      │ │
             │ │ ┌───────────┐ │ │
             │ │ │   仕様    │ │ │
             │ │ │ ┌───────┐ │ │ │
             │ │ │ │ 要件  │ │ │ │
             │ │ │ └───────┘ │ │ │
             │ │ └───────────┘ │ │
             │ └───────────────┘ │
             └───────────────────┘

まだこの図自体も発展途中です。

ただ、このフレームワークを考えていたことが、個人開発で思わぬ効果を生み始めました。

実装で迷ったとき、「どこで迷っているのか」が分かるようになった

個人開発をしていると、当然ながら実装中に迷うことがあります。

例えば、

「この処理はどこに置けばいいんだろう?」

「この画面では何を表示するべきなんだろう?」

「そもそも、この機能って必要なんだろう?」

といった疑問が出てきます。

以前なら、こうした問題をまとめて「設計で迷っている」と考えていたように思います。

しかし、最近は少し違います。

「この処理はどこに置けばいいんだろう?」なら、設計の問題かもしれません。

「この画面では何を表示するべきなんだろう?」なら、仕様が曖昧なのかもしれません。

「そもそも、この機能ってなぜ必要なんだろう?」なら、要件まで戻る必要があるかもしれません。

つまり、

「設計で迷っている」のではなく、「その前提となる仕様が曖昧」なのではないか

のように瞬時に何に迷っているのかの判断ができるようになってきました。

これは、自分にとってかなり大きな変化でした。

瞬時にこの判断ができるようになることで、無駄に実装をこねくり回して悩むことが減るでしょう。

どの工程に戻って、どのような合意形成をするべきかという判断が瞬時にできるようになるはずです。

そういえば、要件と仕様の違いをちゃんと理解していなかった

ここまで考えていて、もう一つ気になったことがあります。

私はこれまで、要件と仕様という言葉を普通に使って開発していました。

しかし、

「要件と仕様は何が違うのか?」

と改めて聞かれると、実は明確に説明できませんでした。

そこで、この機会に要件と仕様の境界を自分なりに整理してみることにしました。

要件は What / Goal、仕様は How

現時点では、私は次のように整理しています。

要件は What / Goal です。

つまり、

システムによって何を達成する必要があるのか

を表します。

一方、

仕様は How です。

つまり、

その要件を満たすために、システムはどのように振る舞うべきなのか

を表します。

例えば、家計簿アプリを考えてみます。

「ユーザーが月ごとの支出を把握できるようにしたい」という目的があるとします。

これをシステムの要件として、

ユーザーが月ごとの支出額を確認できること

と表現できます。

ここでは、まだ具体的な画面やボタンの動作までは決めていません。

そこから仕様として、

月を選択すると、その月の支出合計を表示する。

支出をカテゴリごとに集計して表示する。

といった具体的な振る舞いを定めていきます。

つまり、

要件
「何を達成する必要がある?」 = What / Goal
       ↓
仕様
「システムはどう振る舞う?」 = How
       ↓
設計
「その振る舞いをどういう構造で実現する?」
       ↓
実装
「その構造をどうコードにする?」

という関係になります。

「迷い」を上流へ遡る

この整理をすると、実装中の迷いについても、少し違った見方ができるようになります。

例えば、

「このボタンを押したら何が起きるべきなんだ?」

と迷った場合、それは設計の問題ではなく、仕様が定まっていない可能性があります。

さらに、

「そもそも、このボタンは必要なのか?」

となれば、仕様よりさらに上流の要件を確認する必要があります。

逆に、

「この動作をすることは決まっている。では、この責任をどのクラスに持たせるべきか?」

という問題なら、設計の問題です。

つまり、実装で迷ったときに、

「どうコードを書けばいいのか?」

だけを考えるのではなく、

「私は今、どの工程のモデルについて迷っているのか?」/「どの工程のモデルが曖昧なのか?」

と考えることができます。

そして、

要件が曖昧なのか?
    ↓
仕様が曖昧なのか?
    ↓
設計が曖昧なのか?
    ↓
実装方法が分からないだけなのか?

と、一つずつ上流へ遡っていくことができます。

モデリングのフレームワークを作っていたから見えるようになった

今のところ、この考え方が本当にどこまで一般化できるのかは分かりません。

また、要件・仕様・設計の境界も、開発現場や組織によって異なるでしょう。

それでも、自分の個人開発では、この考え方によって「迷い」の中身をより短時間で言語化できるようになってきました。

私が今作ろうとしているモデリングのフレームワークは、

「前工程の成果物をどのように捉え、それをどのようなモデルとして表現し、次のモデルへ変換していくのか」

を考えるためのフレームワーク。

つまり、モデリングそのもののフレームワークです。

まだ大枠しかありません。

しかし、実装で迷ったときに、

「これは設計の問題なのか?」

ではなく、

「自分はいま、どのレイヤーの、どの前提をモデリングしているのか?」

と考えられるようになったことは、このフレームワークを作る上で大きな一歩だったように思います。