1

ドメイン駆動型の設計コンセプトを使用してシステムを設計していますが、いくつかのことに苦労しています。「ドメイン」とは、基本的に私が勤務する会社の業務システムです。依存性注入も使用しています。したがって、私のモデルには、典型的なビジネス システム (従業員、注文、請求書、預金など) に関連するものがあります。現在、ユーザー (別名従業員) が預金を作成して未払いの請求書に適用できる現金転記アプリケーションを作成しようとしています。私が抱えている問題は、会計トランザクションを処理するために外部のビジネス システム (Microsoft Dynamics Nav) も使用していることです。したがって、基本的に私は2つの異なるデータベースを扱っています。そこで、現金転記アプリケーションのために、ドメイン オブジェクト Deposit と DepositLine をモデル化しました。ドメインには、デポジットの永続化を担当する IDepositRepository インターフェイスもあります。システムからデポジットを取得するには、データベースから直接取得したいだけです。ただし、デポジットを作成するには、Dynamics Nav Web サービスを使用する必要があります。これは、私が知らないバックグラウンドで実行される特定のロジックがあるためです。私は、自分のバージョンの預金オブジェクトを Web サービスに適した預金オブジェクトに変換できる腐敗防止レイヤーの概念を検討し始めました。そこで、今思い描いているのは次のようなものです。デポジットを作成するには、Dynamics Nav Web サービスを使用する必要があります。これは、私が知らないバックグラウンドで実行される特定のロジックがあるためです。私は、自分のバージョンの預金オブジェクトを Web サービスに適した預金オブジェクトに変換できる腐敗防止レイヤーの概念を検討し始めました。そこで、今思い描いているのは次のようなものです。デポジットを作成するには、Dynamics Nav Web サービスを使用する必要があります。これは、私が知らないバックグラウンドで実行される特定のロジックがあるためです。私は、自分のバージョンの預金オブジェクトを Web サービスに適した預金オブジェクトに変換できる腐敗防止レイヤーの概念を検討し始めました。そこで、今思い描いているのは次のようなものです。

ドメイン層

- Models
    - Deposit
    - DepositLine
- Repositories
    - IDepositRepository

インフラ層

- Data
    - Repositories
        - DepositRepository
- DynamicsNav
    - Services
        - INavCashManagementService
    - Translators
        - IDepositTranslator
    - Adapters
        - INavAdapter

今、私は DepositRepository を次のように実装するかもしれないと考えました:

public class DepositRepository
{
    private INavCashManagementService navCashManagementService;

    public DepositRepository(INavCashManagementService navCashManagementService)
    {
        this.navCashManagementService = navCashManagementService;
    }

    public Deposit GetDeposit(int id)
    {
        // use nhibernate to get directly from the database
    }

    public void SaveDeposit(Deposit deposit)
    {
        this.navCashManagementService.CreateDeposit(deposit);
    }
}

まず、これは適切な設計ですか?私の次の問題は、ユーザーもデポジットを「投稿」する必要があることです。投稿ルーチンを実行するには、Nav Web サービスも使用する必要があります。しかし、これは永続性の問題というよりもビジネス プロセスに関係しているため、リポジトリに適合するとは思えません。だから、投稿ルーチンをどこでどのように呼び出すべきか疑問に思っています。次のようなドメイン サービスを作成する必要があります。

public class CashPostingDomainService
{
    private INavCashManagementService navCashManagementService;

    public CashPostingDomainService(INavCashManagementService navCashManagementService)
    {
        this.navCashManagementService = navCashManagementService;
    }

    public void PostDeposits()
    {
        this.navCashManagementService.PostDeposits();
    }
}

ドメイン駆動設計に関して私が持っている混乱の 1 つは、外部依存関係です。CashPostingDomainService クラスは Nav に外部依存していませんか? 実装がドメイン層にないことは知っていますが、インターフェース自体が依存関係にならないのでしょうか? 同じことが、電子メールの送信などの他の技術的な問題にも当てはまります。IEmailService インターフェースがあり、預金がポストされたら電子メールを送信したい場合、インターフェースを CashPostingDomainService クラスに挿入しますか? それとも、それはアプリケーション ワークフローの一部でしょうか? したがって、これらのオプションのどれが最も理にかなっていますか (もしあれば):

1

public class DepositController
{
    private ICashPostingDomainService cashPostingDomainService;
    private IEmailService emailService;

    public DepositController(
        ICashPostingDomainService cashPostingDomainService, 
        IEmailService emailService)
    {
        this.cashPostingDomainService = cashPostingDomainService;
        this.emailService = emailService;
    }

    public void PostDeposits()
    {
        this.cashPostingDomainService.PostDeposits();
        this.emailService.NotifyDepositsPosted();
    }
}

2

public class DepositController
{
    private ICashPostingDomainService cashPostingDomainService;

    public DepositController(
        ICashPostingDomainService cashPostingDomainService)
    {
        this.cashPostingDomainService = cashPostingDomainService;
    }

    public void PostDeposits()
    {
        this.cashPostingDomainService.PostDeposits();
    }
}

public class CashPostingDomainService
{
    private INavCashManagementService navCashManagementService;
    private IEmailService emailService;

    public CashPostingDomainService(
        INavCashManagementService navCashManagementService,
        IEmailService emailService)
    {
        this.navCashManagementService = navCashManagementService;
        this.emailService = emailService;
    }

    public void PostDeposits()
    {
        this.navCashManagementService.PostDeposits();
        this.emailService.NotifyDepositsPosted();
    }
}

助けてくれてありがとう!

4

1 に答える 1

1

これは適切な設計ですか?

私には問題ないようです。重要なことは、リポジトリが Nav 側のことを気にせず、腐敗防止レイヤーに処理させることです。同様の例については、こちらをご覧ください。

実装がドメイン層にないことは知っていますが、インターフェース自体が依存関係にならないのでしょうか?

(不可知論的であると思われる) サービス インターフェイスの名前に "Nav" が含まれているため、そのように感じるかもしれません。実装として Navまたはその他の ERP を持つ可能性のあるサービスの抽象化を反映するには、名前を に変更する必要がありますICashManagementService

IEmailService インターフェースがあり、預金がポストされたら電子メールを送信したい場合、インターフェースを CashPostingDomainService クラスに挿入しますか? それとも、それはアプリケーション ワークフローの一部でしょうか?

どちらかを選択するのは、アーキテクチャ上の決定です。

オプション 1. 電子メールの送信は、入金ポスティング ドメイン操作の本質的な部分であることを意味します。ドメイン モジュールを取得して別のアプリケーションで再利用する場合、デポジットを投稿すると、そのアプリケーションに関するメールが自動的に送信されます。これはあなたのコンテキストで行うのが正しいことかもしれませんし、もう少し一般的なものにしたいかもしれません (操作の後にフィードバックを送信するが、ドメイン サービスでこのフィードバックをメールにするか、ログ ファイルにするかを決定しないなど)。 .)

オプション 2. は、デポジットをポストした後に発生する一連のイベントがアプリケーション固有であることを意味します。つまり、ビジネス/ドメイン レベルではなく、ユース ケース レベルです。どのアクションを実行するか (電子メールの送信など) を決定するのは、コントローラー (またはアプリケーション サービス) 次第です。その結果、ドメイン層に基づくさまざまなアプリケーションが、さまざまなアクションを実行することを決定する可能性があります。これは、複数のアプリケーションがメールの送信を選択した場合、これらのアプリケーション間でコードが重複する可能性があることも意味します。

于 2012-10-04T14:06:21.870 に答える