See the Elephant

1992生まれのプログラマが書くエンジニアブログ

【DDD】ドメインモデルとドメインサービスについて調べたがまだよくわかっていない

昨夜書いたブログにコメントが来た

sqlアンチパターン マジックビーンズに対するコメント

namu-r21.hatenablog.com

f:id:namu_r21:20190725233029p:plain

f:id:namu_r21:20190725233042p:plain

ちょこっと調べ、友人の言葉を借りた一旦の理解は以下。

正直よくわからないことがわかったって段階。

ドメインモデルとドメインサービスって何が違うんだ?

codezine.jp

ドメインサービス:エンティティや値オブジェクトの責務ではないドメインモデルのロジック(複数のドメインオブジェクトを使って計算する処理やファサード

この書き方からするに

ドメインモデルがドメインサービスを包含する ように見える

抜粋

 一般的な「サービス」という言葉には、複雑なビジネスロジックを使いやすい粒度にまとめたコンポーネントというイメージがあります。 DDDの「ドメインサービス」は従来の「サービス」が示すものとは異なります。「ドメインサービス」は粒度が粗いコンポーネントではなく、トランザクションの責務を担うわけでもありません。 ドメインサービスの役割は、ドメインモデルが扱う「粒度の細かい処理」を担うものです。その処理がエンティティ(5章)/値オブジェクト(6章)/集約(10章)でもない場合に、ドメインサービスとして実装します。そのため、ドメインサービスはユビキタス言語として表現されます。

んーわからん

ドメインモデルとは

ドメインモデルをまず考えたほうがよさそう

https://codezine.jp/article/detail/11221

「アプリケーション」とは、広義の意味では「システム」全体と同じ意味となりますが、本稿では、ドメインモデルを使用するクライアントである「ユーザーインターフェイス層」「アプリケーション層」について紹介します。

f:id:namu_r21:20190725233156p:plain

この図を見る限り

ドメインモデルがドメインサービスを包含する ように見える

は多分間違ってないな。

じゃ、アプリケーションサービスとドメインサービスは何が違うんだろう。

ここがはっきりすると「ドメイン」の意味する境界が見えそう。

アプリケーションサービス

非常に薄く、ドメインモデル上のタスクの調整に使うロジック(腐敗防止層の変換・アダプター等)

とのこと。つなぎ役、程度で理解しておくか。例えばcontrollerから呼び出されるロジックがこの辺りの話になるんだろうか?

https://www.ogis-ri.co.jp/otc/hiroba/technical/DDDEssence/chap3.html

●Anticorruption Layer(腐敗防止層)パターン 新規に構築するアプリケーションも、たいていはレガシーなど既存の外部システムと連携しなければならない。既存システムが持つドメインモデルは、これから構築しようとする新しいドメインモデルにはそぐわないことが多い。両者のモデルの対応付けが容易でない場合は、新システムと既存システムとの間に隔離層(腐敗防止層)を設けて、そこで両方向に対するモデルの変換を実装して両者のモデルを完全に独立させてしまう。ただし、腐敗防止層の構築には大きなコストがかかるので注意。

この表現から察するに、ビジネスクリティカルな知識は持たずデータのマッピングのような薄いロジックを担当するような層みたいだな。

アプリケーションサービスは、ある機能とある機能のつなぎ目、インタフェース、アダプターという単語で説明されるようだ。

と考えると、 アプリケーションサービスが知らないほとんどのビジネスロジックドメインモデルの中に閉じる ことになる。

https://codezine.jp/article/detail/10318?p=2

// 「ビジネス優先度を合計する」メソッド
    public BusinessPriorityTotals businessPriorityTotals(
            TenantId aTenantId,
            ProductId aProductId) {

        int totalBenefit = 0;
        int totalPenalty = 0;
        int totalCost = 0;
        int totalRisk = 0;

        // リポジトリからBacklogItemのコレクションを取得
        Collection<BacklogItem> outstandingBacklogItems =
                this.backlogItemRepository()
                    .allOutstandingProductBacklogItems(aTenantId, aProductId);

        // 複数のBaklogアイテムの集計処理を実施
        for (BacklogItem backlogItem : outstandingBacklogItems) {
            if (backlogItem.hasBusinessPriority()) {
                BusinessPriorityRatings ratings =
                        backlogItem.businessPriority().ratings();

                totalBenefit += ratings.benefit();
                totalPenalty += ratings.penalty();
                totalCost += ratings.cost();
                totalRisk += ratings.risk();
            }
        }

       // 戻り値であるBusinessPriorityTotalsの値オブジェクトを設定
        BusinessPriorityTotals businessPriorityTotals =
                new BusinessPriorityTotals(
                        totalBenefit,
                        totalPenalty,
                        totalBenefit + totalPenalty,
                        totalCost,
                        totalRisk);

        return businessPriorityTotals;
    }

コードを引用する。例えば、このような状態を持たず複数のドメインオブジェクトを組み合わせ、変換を行う処理をドメインサービスと呼ぶらしい。


ここまで調べてみてわかったが、まずDDDの前提知識である境界づけられたコンテキストや値オブジェクト、エンティティといった概念から順に抑えないとよくわからなさそう。

友人が言う言葉に補足して以下のような理解で今回はとどめておく。