4

DDD アーキテクチャを利用するようにリファクタリングする予定の WinForms アプリケーションがあります。まず、私はアーキテクチャ自体に頭を悩ませようとしています。Evans の本と Vernon の本を持っていますが、アプリケーションですぐに直面する 3 つのシナリオに苦労していることに気づきました。概念設計プロセスで考えすぎたり、厳密すぎたりするのではないかと心配しています。

1.) DDD に関する Pluralsight チュートリアル内で提供された例を利用して、スピーカーは、さまざまな境界付けられたコンテキストを独自のソリューションで表す必要があることを指摘しました。ただし、サービス指向ではない winforms アプリがある場合 (これは最終的に変更され、この質問の多くは意味がなくなります)、これは実行可能ではないようです。したがって、相互依存関係がないことに注意して、これらを異なるプロジェクト/名前空間に分離するという前提で運用しています。これはそれについて考える正しい方法ですか、それとも明らかな何かが欠けていますか?

2.) 異なる境界付けられたコンテキストの別々のプレゼンテーション レイヤーに属する他のモジュール/ウィンドウを起動するナビゲーション UI があります。ERP アプリケーションを起動したときに最初に開くウィンドウを考えてみてください。これは特定の BC 内にきれいに収まらないため、このようなものを適切に実装するにはどうすればよいでしょうか。これは共有カーネル内に収まる必要がありますか?

3.) ジョブ管理境界コンテキストと評価/原価計算境界コンテキストがあります。ジョブが作成されたときにその詳細が評価されるのは、ビジネス プロセスの一部です。これには独自の UI などがありますが、このプレゼンテーションがまだジョブ管理のコンテキスト内に適切に収まっていることは非常に良いと思います。ただし、これらの詳細の実際の評価プロセスは絶対にすべきではありません。bc は互いに分離されているため、Rating/Costing コンテキストと通信する方法が完全にはわかりません。メッセージングを行うことができることはわかっていますが、非分散アプリにとってはやり過ぎのようです。各 BC は、ある種の API を自己ホストすることもできますが、これはやり過ぎのように思えますが、これにより、後で分散アーキテクチャに移行するためのチームの準備が整います。ついに、私の最後のアイデアは、一種のイベントストアであるある種の共有依存関係を持つことです。これがドメイン イベントと同じかどうかはわかりません。ドメイン イベントはそれ自体に別の懸念があるようです。では、これは共有カーネルまたは他のタイプのソリューションに該当するということですか?

前もって感謝します。

4

3 に答える 3

6

1) ソリューションに対応する BC に関するガイダンスはガイダンスであり、厳密な規則ではありません。ただし、非常に必要な分離を提供します。これは、WinForms プロジェクトで引き続き使用できます。たとえば、Customers という BC があるとします。そのためのソリューションを作成し、その中に Customers.Contracts という追加のプロジェクトを作成します。このプロジェクトは、DTO、コマンド、およびイベントで構成される BC のパブリック コントラクトを効果的に格納します。外部 BC は、この契約プロジェクトで定義されたメッセージのみを使用して、顧客 BC と通信できる必要があります。WinForms ソリューションが Customers プロジェクトではなく Customers.Contracts を参照するようにします。

2) 多くの場合、UI は構成の役割を果たし、多くの BC を調整します (複合 UI)。典型的な例は、Amazon の製品ページです。ページをレンダリングするには、さまざまな BC からの何百ものサービスが必要です。

3) 繰り返しますが、これは複合 UI を必要とするシナリオのようです。プレゼンテーション層は、異なる BC 間を仲介できます。BC は疎結合ですが、BC 間には関係があります。あるものは他のものの下流にあり、あるものは上流にあり、あるいはその両方です。それぞれに、関連する BC と統合するための腐敗防止レイヤーであるポートがあります。

于 2013-05-24T20:51:54.483 に答える
3

まず最初に、メッセージ バスについて話しているのを見たので、まず BC 統合について話す必要があると思います。

BC 間の通信にメッセージ バスは必要ありません。ここでは、さまざまな BC を統合する方法について説明します。

各 BC でいくつかのパブリック インターフェイスを公開し (ドメイン コマンド、クエリ、およびイベントと同様)、この呼び出しを他の BC に変換する中間層をインフラストラクチャに配置します。

BC で公開されたコマンドのインターフェイスの例を次に示します。

public interface IHandleCommands
{
    void DoSomething(Guid SomeId,string SomeName);
}

公開されたイベントにも同様のものがあります

public interface IPublishEvents 
{
   void SomethingHappened(Guid SomeId,string SomeName);
}

最後に、公開されたデータ (つまり、CQ(R)S のクエリ) には別のインターフェイスがあります。これにより、ドメイン モデルとクエリ コードの間の結合をいつでも削除できることに注意してください。

public interface IQueryState
{
    IEnumerable<SomeData> ActiveData(DateTime From=DateTime.Minvalue, ... );
}

そして、私の実装は次のようになります。

public class SomeAR:IHandleCommands
{
    IPublishEvents Bus;

    public SomeAr(IPublishEvents Bus) 
    {
       this.Bus = Bus;
    }

    public void DoSomething(Guid x,string y)
    {
       Bus.SomethingHappened(SomeId: x,SomeName: y);
    }
}

結局のところ、考えてみると、ドメイン イベントなどはメッセージングなしでも実行できます。メッセージ クラスをインターフェイス メンバーに置き換え、ハンドラーを BC に挿入されるインターフェイス実装に置き換えるだけです。

これらのハンドラーは、他の BC でコマンドを呼び出します。それらは、さまざまな BC を結合する接着剤のようなものです (ワークフロー/ステートレス サガなどを考えてください)。

これはハンドラーの例です。

public class WorkFlow : IPublishEvents
{
  public void SomethingHappened(Guid SomeId,string SomeName) 
  {
     AnotherBC.DoSomething(SomeId,SomeName);
  }
}

これは多くの労力を必要としない簡単なアプローチであり、私はこれを使用して大きな成功を収めています. 後で本格的なメッセージングに切り替えたい場合は、簡単に行うことができます。

UI に関する質問に答えるには:

私はあなたがこれについて厳しすぎると思います.

私のドメインが UI から分離されている (または簡単に分離できる) 限り、単一の UI プロジェクトから簡単に開始でき、どこかで痛みを感じ始めた瞬間にそれを分割できます。ただし、コードを分割する場合は、プロジェクト構造が一致するように BC ごとに分割する必要があります。

この方法で UI を構築することが、私にとって最も効率的な方法であることがわかりました...

于 2013-05-25T07:59:27.417 に答える