設計者の発言

業務システム開発とデータモデリングに関する語り

自社サービスはOOP、業務システムはDOAで作ろう

 前回記事で、一般的な業務システムの開発において、DDD(ドメイン駆動設計)が提唱する「ユビキタス言語」の実践は難しいと説明した。そもそもDDDを含むオブジェクト指向プログラミング(OOP)は、一般的な業務システムの開発には向いていない。とはいえ、企業がOOPで内製することが合理的なものは存在する。企業に売上をもたらす製品(プロダクト)系のソフトウエアだ。典型的な例が「自社サービス」の運用を支える「サービス支援システム」である。これと業務システムとの関係を見よう。

自社サービスと業務システムの関係

 自社サービス、つまり、WEB上で提供される有償サービスで稼いでいる企業があるとして、そのシステム構成はどのような形になるだろう。まずは、企業システム全体の一般形について確認しておこう(図1上 参考記事)。

f:id:dbconcept:20210926083111p:plain

図1.企業システムの一般形とサービス支援システムの位置づけ

 この中のaがいわゆる業務システムで、決算システム(d)および共用データ管理システム(e)と連係しつつ運用される。「事業データ管理システム(a)」と呼称されていることからもわかるように、基本的に1事業について1個ずつ用意される。「自社サービスで稼ぐ事業」を擁する企業であれば、サービス支援システム(s1,s2,s3)と事業データ管理システム(a)との関係は、図1下のように模式化される。

 a(事業データ管理システム)とS(サービス支援システム:s1,s2,s3)との連係様式を説明しよう。aでは、商品(サービス構成)情報、顧客情報、契約情報、売上・請求情報等が扱われる。顧客がサービスにログインすると、Sはaが提供するWeb-APIを用いてユーザ認証したうえで、契約内容をセッションに取り込む。ユーザがサービスを利用すれば、利用実績(セッション情報)がS上に記録される。これが定時のバッチ処理でaに渡され、売上の算定基礎情報となる。さらに月次の売上情報は決算システム(d)に渡されるとともに、aでは請求情報に加工されて請求書が発行・送付される。

 この図解において重要なのは、aとSとを責務の異なるソフトウエアとみなして分離している点だ。この企業が既存の2つのサービスS1,S2を運用しているとして、新しいサービスS3を投入することになったとしよう。この図のような「分離型」であれば、サービスS3向けの支援システムを新規開発すればよい。aの改修が要るとしても最小限度で済む。もしaと一体化した形のS3を追加するとしたら、a部分の大掛かりな作り込みが必要になる。売上が低迷しているサービスを廃止する場合でも分離型が有利だ。極端に言えば、対応するSを停止するだけでいい。

 分離型は人員リソースをスケールしやすいという意味でも合理的だ。図1のa、S1、S2、S3のそれぞれに開発・保守チームがあてがわれる。合計4チームで、それぞれのチームが数名の技術者を含むとイメージしてもらえばよい。ソフトウエアの規模感としてaは比較的大きく、個々のSの10倍はあるのだが、aにあてがわれるチームは1チームでかまわない。なぜならaは「稼ぐソフトウエア」ではないからだ。いっぽうS群については、個々にチームをあてがって維持することが経営的に許容される。ようするにS1、S2、S3はこの企業が売上を獲得するための「製品(プロダクト)」であって、手間暇をかける意義がある。ただしサービスが低迷している場合には、廃止して開発チームも撤退することになるが、aについては倒産しない限りチームは張り付き続ける。

OOPDOAの「融合」ではなく「使い分け」を

 次に、それぞれの「適切な実装手段」を考えよう。現時点で調達可能な実装技法として、DDDを含むオブジェクト指向プログラミング(OOP)とデータ指向アプローチ(DOA)の選択肢を考えると、図1下で示した使い分けが明解かつ合理的である。それぞれのモジュールの以下のような特性から納得してもらえるだろう。

  サービス支援システム(S):OOP+NoSQLが向いている
  ・そのものが売上をもたらす
  ・データ要件が単純
  ・市場の変化に影響されやすい
  ・ユビキタス言語に関するチームの裁量が大きい

  事業データ管理システム(a):DOA+RDB+ローコードが向いている
  ・そのものは売上をもたらさない
  ・データ要件が複雑
  ・市場の変化に影響されにくい
  ・ユビキタス言語に関するチームの裁量が小さい

 両者の異質さがよくわかるが、決定的な違いは「データ要件の複雑さ」だ。S系のデータ要件は単純で、極端に言えばサービスの利用実績が記録されるだけでよい。上述したように、顧客情報や契約内容については、API経由でaから確保出来るからだ。しかも、利用実績は新規追加されるばかりで更新されることがないか少ないので、更新時異状の心配もない。スケールしにくいRDBを使う必要もない。いっぽうaでは、サービス構成、契約、月次請求といった多彩で複雑なデータ構造が扱われる(図2)。複合主キーや複雑な更新処理のオンパレードなので、RDBやデータモデリングが欠かせない。ただし「稼ぐソフトウエア」ではないので、開発・保守の手間を惜しまねばならない。ローコード基盤のような合理化手段を積極的に取り入れたいところだ。

f:id:dbconcept:20210926083444p:plain

図2.有償サービスで稼ぐ企業のデータモデル例

 こういったシステム構成や構成要素の特性が理解されていないと、さまざまな無理が生じる。たとえば、「自社サービスで稼いでいつかは上場」と意気込んでスタートアップした企業が、Sとa(の一部)とを一体化した形で全体をOOPしたりする。その場合、商売が発展する過程で商品構成や契約管理や課金処理が複雑化し、事務作業にしわ寄せがいくようになる。そうなる前に分離型としてリファクタリング出来ればラッキーだが、うまくいったとしても最初から分離しておいた場合と比べ、あまりに非効率だし段取りが悪い。

 また、Sの開発と同じノリで、aの内部までをマイクロサービスの組み合わせにしたりする。「業務システムとマイクロサービス」でも指摘したが、aを複数のマイクロサービスに分割して、それぞれに開発チームをあてがうような贅沢は許されない。繰り返すが、aはSのような「稼ぐソフトウエア」ではないからだ。aについてはあえてモノリシックに組み立て、1チームで賄えるように省力化すべきだ。いっぽうSにはガッツリ稼いでもらうために、MSA的に構成してコストをかける意義がある。

 ようするに、開発対象の特性や社会的文脈に応じてOOPやらDOAやらを使い分けよう、という話なのだが、その実践は想像以上に難しい。ORM(object-relational mapping)などはその壮大な失敗例だと私は見ている。RDBとORMを選定している時点で、複雑なデータ要件を伴う開発対象を無理やりOOPしようとしていることが明白だ。「OOPだけでどんなシステムも作れる」にも「DOAだけでどんなシステムも作れる」にも無理がある。そして、求められているのは、OOPDOAの「融合」でも「いいとこ取り」でもない。開発対象の特性を見極めたうえでの「使い分け」だ。企業活動に関わるIT技術者は、双方のスキルを身につけるか、それぞれの特性だけでも理解しておいてほしい。「斧で鉛筆を削る」とか「カッターナイフで杉を伐採する」といった非効率なやり方で人生を無駄遣いしないため、そして何よりもユーザ企業のためだ。