ビジネス的関心とシステム的関心

エンタープライズ・アプリケーションを実装する上で、明確に区別しておくべき2つの概念に関する私見の整理。

導入

ソフトウェアを作る上で最も重要な概念の1つに、「抽象」あるいは「レイヤ化」といったものがあると思います。どのようなレイヤを設定するのか、ということは設計思想に直結するもので、画一的な正解があるというものではありません。ただ、特にエンタープライズ・アプリケーションを考えた場合にきわめて重要になってくるのが「ビジネス」と「システム」の区別であると言えるのではないでしょうか。以前のエントリ(開発現場の"Clean Code")では、トランザクションスクリプトの実装に焦点を当て、「意味のレベル」と「実装のレベル」の区別について記述しましたが、今回はコードの実装ということに限定せず、もう少し広い枠組みで、この「ビジネス」と「システム」について考えていきたいと思います。

外部設計と内部設計

「外部設計」「内部設計」というと、まずウォーターフォール開発が頭に浮かぶかもしれません。しかしそれに限定しなくても、ソフトウェアの設計ではどこかに「外部」と「内部」の境界が引かれているはずです。この境界は、実質的には「何をするのか」と「それをどのように実現するのか」との間の境界であると考えることができます。このうち前者がビジネス的関心であり、後者がシステム的関心です。ここで重要なのはビジネス的な観点から見た品質は、外部設計に示された仕様を満たしていることを検証することによって保証されるということです。多少乱暴な言い方をすれば、ユーザの立場=ビジネスの立場からすれば、外部仕様さえ保証されていれば中身は問わないということですね。これは普段私たちが、例えばテレビを見る時にまったく配線を意識しないのと似ていると思います。

ふるまいの変更とコードの修正

外部仕様、すなわちユーザから見たふるまいを考える時に、内部的なシステム的関心のことを切り離しておくのはそう難しいことではありません。しかし、内部設計およびそれに従った実装を行う際には注意が必要になります。実装時にはビジネス的な関心とシステム的な関心の両方を扱わなければならないからです。例えば何らかの理由でコードに修正を加える場合、それが純粋にシステム的なものであって、ビジネス的なふるまいに影響を与えるものではないことは慎重に確認すべき事柄です。このことは、内部設計においてふるまいを示す「What」が実装方法を示す「How」に完全に置換されてしまっている場合において、より深刻な問題となってきます。

まとめ

結局のところ、いわゆる業務アプリケーションを実装している限り、「単なるコーディング」という作業は存在し得ないということです。しかし、実装時にビジネスとシステムを適切に識別するためには、コーディングを行う人が、今自分が書いているコードがどのようなビジネス的関心に寄与するものであるのかを正確に理解している必要があります。これにはコーディングをする人の意識がきわめて重要になってきます。


コーディングを行う人の意識がビジネスに向いている時、その人とビジネス的ふるまいの設計者とを結びつけるための最適なドキュメントは外部設計書です。そこで相互のコミュニケーションを円滑に進めるためには、「手続き的に記述されたドキュメント」と「手続き的に実装されたトランザクションスクリプト」とがノイズなく平行している必要があります。「開発現場の"Clean Code"」において「読みやすさ」という表現を用いて記述していたのは、この平行性を確保するためのプラクティスでした。

最後に

余談ですが、このような観点からふるまい駆動開発を見た時に興味深いのは、ユーザから見たシステムのふるまい、つまり外部仕様を、受入基準と合わせて実行可能な形で定義するためのテンプレートが準備されている点であると言えるでしょう。BDDはビジネスとシステムとの間に明確な責任分解点を設定する開発手法であると言えます。対照的なのがドメイン駆動設計で、これは「そもそもこれはどういうものであるのか」という水準でビジネスを把握し、そこで得られたモデルを実装していくものです。BDDとDDDではビジネスとシステムの境界設定をするやり方が本質的に異なるんですね。これについてはまた別の機会に整理したいと思います。