web-dev-qa-db-ja.com

DDD:グローバル固有IDと代理

例から始めましょう:エンティティBookがあります。一意のIDがあります:Isbn-Stringをラップする値オブジェクト。これはUUIDです。

Bookエンティティには、リポ(sql db)からのサロゲートIDも必要です。私たちができるように、それが必要です。データベースは文字列よりも番号で検索するため、より高速に本を検索できます。

私が読んだことから、代理キーはBooksインターフェイスから非表示にする必要があります。しかし、私たちはそれを使用して、より速く本を見つけることを望んでいます。

これを適切に処理する方法は?

[A]BookgetSurrogateId()(またはより適切な名前)を追加するだけです。これはエンティティを汚染しますが、そのKISSを汚染します。

[B]自然なもののサロゲートキーを見つける責任を負うレポを持つことができます。たとえば、BookRepositoryには次のメソッドがあります。

long toSurrogateKey(Isbn isbn) {
     // lookup the cache
     // if not found, lookup the db
}

代理キーを返すには-もちろん、これらの値はローカルにキャッシュできるため、毎回dbを検索する必要はありません。このメソッドはpublicであってはなりません(右)?

[C]さらに進んで、代理キーをリポジトリ固有のキーと考えることができます。 Bookはインターフェイスであり、SqlBookはリポジトリで作成された実装である場合があります。このSqlBook実装は、リポジトリに必要なすべての追加情報を格納できます。この場合、サロゲートキーはSqlBookのプロパティの1つとして保持されます-SqlBookのユーザーはBook、つまりサロゲートIDを認識していません。

したがって、上記のメソッドは次のようになります(SqlBookクラスで定義):

long toSurrogateKey(Book book) {
     return ((SqlBook)book).getSurrogateId();
}

ここでの唯一の欠点は、Book(およびその他のエンティティ)がリポジトリ対応のファクトリによって作成される必要があることです。言い換えると、SqlFactorysを作成するファクトリのSqlBook実装が必要です。

これについて何か知恵はありますか?

5
lawpert

私たちができるように、それが必要です。データベースは文字列よりも番号で高速に検索するため、より高速に本を検索できます。

サロゲートキーは、仮説的なパフォーマンスの問題ではなく、主キーを構築するための統一された方法を提供するため、主に追加する必要があります。それらは、外部キーとして誤用するため、モデルの半分以上が別々の場所に分散されるようなIsbnのようなビジネスデータを回避するのに役立ちます。

「私が読んだことによると、代理キーはBooksインターフェースから非表示にする必要があります」。

たぶん、この目的を誤解しているだけなのでしょうか?サロゲートキーは、ドメインの専門家とモデルについて話し合うときに非表示にする必要がある技術的な詳細ですが、モデルの実装に対する視点を変更するときにそれらを確認しても問題ありません。したがって、[A]を使用しますが、getSurrogateId()アクセサーがドメインモデルのグラフィック形式で表示されないようにします。

5
Doc Brown