ルックアップテーブル:ドメインモデルのリークですか?


10

あなたは会社を追跡するシステムを構築しています。これらの企業には連絡先があります。これらの連絡先は、請求/支払い、販売、注文、カスタマーサポートなど、特定の種類の質問にのみ回答する専門家であることがよくあります。

ドメイン駆動設計とオニオンアーキテクチャを使用して、これを次のタイプでモデル化しました。

  • 会社
    • 連絡先あり
  • 連絡先
    • 連絡先タイプがあります
  • ContactType(列挙型)
  • CompanyRepository(インターフェース)
  • EFCompanyRepository(外部アセンブリで定義、EntityFrameworkを使用、CompanyRepositoryを実装)

私たちのチームは、このアプリケーションのデータベースをモデル化する方法について意見が分かれています。

サイドA:リーンDDDers:

  • 連絡先に有効なContactTypeを定義するのはドメインの仕事です。不明なContactTypesが保存されていないことを検証するためにデータベースにテーブルを追加することは、リークのあるドメインの兆候です。ロジックが広すぎます。
  • 静的テーブルをデータベースと対応するコードに追加することは無駄です。このアプリケーションでは、データベースが1つの問題を解決します。問題を永続化し、それを私に返します。追加のテーブルと対応するCRUDコードを書くのは無駄です。
  • 永続化の戦略を変更することは可能な限り簡単でなければなりません。そのビジネスルールを変更する可能性が高くなります。SQL Serverのコストが高すぎると判断した場合、スキーマに入力したすべての検証を再構築する必要はありません。

サイドB:伝統主義者[それはおそらく公平な名前ではありません。DBCentrists?]:

  • コードを読み取らなければ意味のないデータをデータベースに置くことは悪い考えです。レポートやその他の消費者は、値のリスト自体を繰り返す必要があります。
  • オンデマンドでdbタイプの辞書をロードするためのコードはそれほど多くありません。心配しないでください。
  • このソースがデータではなくコードである場合、変更時に単純なSQLスクリプトではなくビットを展開する必要があります。

どちらも正しいか間違っているかではありませんが、そのうちの1つはおそらく長期的にはより効率的であり、初期開発、バグなどの開発時間を数えます。このスタイルのコードを書く他のチームは何をしますか?


私は、データベースにルックアップテーブルを用意し、アプリケーションコードのルックアップテーブルに基づいて列挙型を生成するコード(.NETのT4テンプレート)を用意します。
プログラマー

@JasonHolland T4テンプレートは実際にクエリを実行しますか?それ以外の場合は、予期された名前の空の列挙型以上を生成する方法がわかりません。
ドリュー


静的な値を持つテーブルの場合、CRUDコードをいくつ書く必要がありますか?それをスクリプト化して、完了します。
JeffO 2015年

2
「まあ、それは報告する意味がありません」という伝統的なCRUD主義の議論は、出発点ではありません。システムのその他の責任(つまり、報告)を導入するとすぐに、適切に処理する必要のあるビジネス要件が見つかります。データベースは、アプリケーション独自の保護された状態を格納およびロードするために存在します。レポートの作成を許可すると、アプリケーションとレポートを必要とする人々の間の結合が作成されます。DDDが何かについてである場合、それはこれらのコンテキストを分離することです。
Matt

回答:


4

DDDおよびオニオンアーキテクチャを採用することにより、データベースがドメインモデルに次ぐものであると判断しました。つまり、モデル以外にデータベースで操作を行う人は誰もいません。伝統主義者がそれを好まなければ、そもそもDDDの使用に反対するべきでした。

最初のことは明らかです。モデルに「ルックアップテーブル」が必要です。モデルでは、さまざまなタイプの連絡先を区別する必要があります。つまり、すべての型の強く型付けされたリストを保持します。これらの強力な型から、データベースにシリアル化される値へのマッピングも必要です。このマッピングは、データベースモジュール内にあります。ただし、可能なすべてのタイプのリストはモデルに残ります。また、モデルが単一の真の情報源になる場合、データベース内に存在することはできません。または、少なくとも、モデルでリストが変更された場合は、データベースで変更する必要があります。そしてお尻なし!


2

ドメインオブジェクトは、プロセス境界越えるとドメインオブジェクトでなくなります。データベースが永続化ストアにすぎない場合でも、将来のある時点で、ビジネスの要求により、永続化された履歴と一致しないdomaimモデルが変更され、とにかく破損防止レイヤーが必要になります。 ....

そうは言っても、あなたのDBCentristはボートに乗り遅れていると思います。ドメインモデラーは、永続ストアが必要だと言っています。「レポートと他の消費者」は、コメントで指摘されているように、クエリできるものが必要です。適切なインデックスを持つものが必要です。

これらのさまざまな懸念のすべてを1つのデータベースでサポートする必要があるという制約を誰が導入したのですか?それを押し戻すとどうなりますか?

検索キーワード:CQRS。


1

enumを文字列表現としてデータベースに格納し、ルックアップテーブルを含めないのが最善の方法です。

明らかにこれの欠点は、より多くのディスク領域を使用し、正規化されないことです。

プラスの側面は、フィールドがdbでその意味を保持していることです。たとえば、列挙型のint値に対応するマジックナンバーで終わることはなく、列挙型が変更されたときにルックアップテーブルのバージョン管理を行う必要がありません。

私はこれをDDDとTradの違いとして特徴づけるかはわかりません。データベース中心主義者対コードの方が私の見解では最高です


最近、データベース自体にこのような列挙型の機能があるかどうか疑問に思います
herzmeister '27 / 10/27

それはDBに依存すると思いますが、MSSQLを使用して、あらゆる種類のクレイジーなCLRを行うことができます。しかし、そのようなことになると、私は「DBが悪い、コードが良い」側にしっかりと
Ewan

@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html、Ewanストアドプロシージャを採用すると、DBはコードになります。(PLv8はすばらしい)。
Sirisian 2015年

@シリシアン、それは混ざり合うことを知っていますか?同様の質問があります。「それはスケールしますか?」
Ewan

列挙型を文字列に変換する外積を行うということですか?おそらく違います。実装方法はわかりませんが、別のテーブルを使用するよりも高速です。それはスケーリングします。これも見つかりました:stackoverflow.com/questions/2318123/…5年後も有効な評価のようです。(私はPostgreSQLと高度に結合したプログラムを作成する傾向があるため、すべての機能を使用しますが、誰もがそれを実行できるわけではありません)。
Sirisian、2015年

0
  • リレーショナルデータベースを使用している限り、テーブルを適切な範囲に正規化する必要があります。正規化は、挿入と更新の異常を防ぐのに役立ちます。
  • 1つのアプリ<-> 1つのデータベースの関係は一般的ではなくなりました。複数のアプリが複数のデータベースを使用でき、1つのデータベースを複数のアプリで使用できるため、データベースに参照整合性を可能な限り適用させることは良いことです。
  • RDBMSはあなたの友達です。
  • 代わりにKey-Valueストレージを使用して、すべてをコードで実行できます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.