会社マスタを継承を利用してモデリングする

パッケージソフトのマスタなどをのぞいてみると、よく「得意先」「請求先」「支払先」「仕入先」「出荷先」などのテーブルがありますよね。これらのテーブルは、大体どのパッケージでも同じように、それぞれ「会社名」「コード」「連絡先」というカラムを持っています。これらカラムをそれぞれのテーブルで持ってしまっているがために、会社名が来年の四月から変わるぞーって時に、いろいろなテーブルを修正するとか、納品書は新しい会社名なのに請求書を出してみたら古い会社名になっていて、修正伝票を起こして再度請求書を出力するところからやり直し、といった作業が発生してしまいます。
だったら、ここはオブジェクト指向的に、「会社」という親エンティティに基本的な属性を集約し、「請求先」「支払先」などは「会社」を継承した子エンティティとして定義したらどうでしょうか。責務が集約されていれば、上記のような問題は解決するはずです。現実の世界でも、「請求先」や「支払先」というモノがあるわけではなく、1つの「会社」というモノが、請求という業務から見たときに「請求先」になり、支払いという業務から見たときに「支払先」になるだけですよね。
であれば、我々が構築する業務システムにおいても、「会社テーブル」と「請求先ビュー」「支払先ビュー」としてモデリングすべきです*1
このようにしておけば、企業が行う業務領域が広がったときにも、「旅行代理店テーブル」や「宿泊施設テーブル」などを追加することで、既存のテーブル構造に影響を与えずに対応できます*2。既存の会社マスタに「旅行代理店フラグ」を追加するだなんて、最低な対応だと思いませんか?

もちろん、このような設計を行うということは、その企業の基幹業務にまで深く踏み込むことになるので、企業側に相当な予算が、構築するベンダー側に相当な覚悟が、それぞれ要求されることになります。これをフルスクラッチで開発する案件なんぞそうそう無く、あってもパッケージの方が実績*3があったり導入効果の予測が立てられるという判断になり、なかなか難しいですね。

*1:ビューで実装することに問題があれば「会社テーブル」と1:1で関連する「請求先テーブル」「支払先テーブル」でも構わない。実際ビューよりも関連テーブルのほうが良いと思う

*2:他のサブシステムで「旅行代理店テーブル」を使わないなら、利用するサブシステムに定義すればよい

*3:赤信号みんなで渡れば〜、という意味で