初めに
ソフトウェア開発には「モデリング」と「ユースケース実装」という二つのプロセスが存在します。
この二つのプロセスについて最近説明をすることが多いため、記事としてまとめてみました。
アプリケーションとは
アプリケーションとは、特定の目的を達成するために設計されたソフトウェアです。
アプリケーションは正味プログラムさえできれば開発することは可能ですが、今日紹介する「モデリング」と「ユースケース実装」
という大きく二つのプロセス/アーキテクチャを採用して作られることが大半です。
アプリケーション開発においてよく使われるような以下のようなアーキテクチャは全てこの「モデリング」「ユースケース実装」
考え方を基に作られています。
- レイヤードアーキテクチャ
- MVC
- クリーンアーキテクチャ
- オニオンアーキテクチャ
モデリングとは
モデリングとは、アプリケーションで扱う概念(ドメイン)を定義、実装していくプロセスになります。
アプリケーションは基本的に何かしらの目的を達成するために作られています。
目的という表現をより噛み砕いた表現にすると、「コンピュータ上で何かしらの物/ことを実行可能・エミュレート可能にすること」です。
例えば「Qiita」というサービスは「コンピュータ上で記事を扱えるようにする」サービスです。
コンピュータ上でしか表現できない概念ももちろん存在しますが、人がインターフェースを返して何かしらインテラクションが取れる以上、アプリケーションは感覚として手に取れるような、輪郭のあるものやことを扱うことが大半のケースになります。
この感覚は普段使っているアプリなどを想像するとすぐ腑に落ちるのではないでしょうか。
モデリングとはつまり、この「アプリケーションで扱う概念」をコードとして落とし込んでいくプロセスになります。
モデリングを行う段階では、基本的に動くものはできあがりません。
このプロセスで実装していくものは、それぞれのモデルに存在するルールやアクションの定義(メソッド定義)になっていきます。
このモデリングを経て、実際の動くアプリケーションを作り上げていくための「ユースケース実装」のプロセスへと向かうことができます。
このモデリングとは、それぞれのアーキテクチャで呼び方はいろいろありますが、往々にして一番内側/下側のレイヤーの実装に関わるプロセスになります。
定義したモデルは、基本的に大きな変更などが入りにくい性質を持ちます。
モデルとは概念をベースに実装されるもの、つまり比較的普遍に近いものに依存しているため、コードの変更が起こりにくいのです。
基本的にソフトウェアは「変更の起こりやすいものが変更が起こりにくいものに依存する」というアプローチが取られることが多いため、このモデリングのプロセスで実装されるコードが一番内側、つまり一番依存されやすいコードになるのです。
それぞれのアーキテクチャで言うと、以下のレイヤーがモデリングのプロセスに対応してきます。
- レイヤードアーキテクチャ: ドメイン層
- MVC: Model
- クリーンアーキテクチャ: Entities
- オニオンアーキテクチャ: Domain Model, Domain Service
ユースケース実装とは
前項で、アプリケーションとは、「コンピュータ上で何かしらの物/ことを実行可能・エミュレート可能にすること」と説明しました。
モデリングの段階では「コンピュータ上で扱いたい物の定義」までの段階までで終わっています。
この定義したものを用いて「コンピュータ上で実現したいことを実現していく」プロセスがこのユースケース実装になります。
モデリングのプロセスで作られた概念が同じでも、実現したいことが異なれば実装する機能やインターフェースなどは大きく異なっていきます。
「ユースケース実装」のプロセスでは、この「アプリケーションで実現したいこと」を定義していくことになります。
例えばQiitaでは「ユーザーがエディタから記事を投稿する」際、以下のような体験を提供するための実装を行なっています。
- 記事投稿時、Organizationに紐づけることができる
- 記事投稿時、記事投稿キャンペーンに紐付けができる
これらの実装は、Qiitaが体験として提供したいものであり、ユースケース層の処理として実装を行なっています。
このユースケース実装のプロセスもそれぞれのアーキテクチャのレイヤーに対応しています。
- レイヤードアーキテクチャ: アプリケーション層
- MVC: Model/Controller
- クリーンアーキテクチャ: Use Cases
- オニオンアーキテクチャ: Application Service
なぜこのようなアプローチを採用するのか
以上のように、アプリケーション開発は大きく「モデリング」「ユースケース実装」というプロセスで開発ができることが多く、それぞれのアーキテクチャでもそれらの考え方を採用しているという紹介をしてきました。
最後に、なぜこのようなプロセスを取る必要性があるのかについて説明を行います。
理論上、今回紹介したような考えを持っていなかったとしても、アプリケーションは開発可能です。
プログラミングを勉強してきた方であれば、一度はオレオレコードでとりあえず動くような形でアプリケーションを作った経験はあるのではないでしょうか。
そしてそのような経験がある方であれば、いかにモデリングを行わずにアプリケーションの機能を作っていくことが大変なのかを理解している方も多いのではないでしょうか。
モデリングというプロセスが威力を発揮するのは初めに機能を作り始めるタイミングではなく、どちらかというと自分以外の誰かが開発を引き継いだり、機能の追加や変更などを行う必要が出てきたタイミングになります。
何も考えずに作られた機能は依存関係が複雑になることが多いです。そしてそれらの依存されているコードの変更頻度は異なるため、全体のコード同士がひきつるような状態になります。
概念を定義することができれば、コードの実装時もその概念を用いて人とコミュニケーションが取れたり、思考を行うことが容易になります。そして概念から作られたコードは比較的変更頻度も低く、安定しています。
このような変更頻度とコードとしての扱いやすさを踏まえると、まずはモデリングをしていくことが重要だ、ということが今までのエンジニアリングの歴史の中のプラクティスとして現代まで継承されています。
以上から、モデリング、そしてモデリングで実装されたコードを用いたユースケースの実装、というプロセスが主流になったのだと考えています。
参考
https://ja.wikipedia.org/wiki/Model_View_Controller
https://gist.github.com/mpppk/609d592f25cab9312654b39f1b357c60
https://little-hands.hatenablog.com/entry/2019/07/26/domain-knowledge