下の図でわかるように、私は研究グループのニーズに合うアーキテクチャ設計の概念実証に取り組んでいます。これらは:
- 再利用可能なビジネス ロジック コンポーネント
- 分離されたデータ モデル
- 分離されたフロントエンド (つまり、Web UI、サービス、コンソール アプリなど)
- すべてのコンポーネント (フロントエンドを除く) は、完全に単体テスト可能 (モックなどを使用) である必要があります。
これを実現するために、基本的に Facade パターンの実装である「接着」コンポーネント (Glue.ConsoleApp) を導入しました。すべてのフロントエンドには、対応するファサードがあります。これは、分離されたコンポーネントの非常に最小限の実装を示す単純な C# ソリューションです。
ファサードはすべてのコンポーネントをリンクしていますが、私の意見では、コードはまだ複雑すぎます。私は、すべてのレイヤーを完全に分離するために、それらすべてが独自のエンティティを定義する必要があり、グルーレイヤーが大量のマッピングを行う必要があるという事実に苦労しています (これが、ValueInjecter を使用するライブラリであり、この作業のほとんどを自動化します)。
以下は、1 つのメソッドですべてが InvoiceLine を表す 3 つの異なるクラスを持つことの複雑さを示すメソッドの例です。
using Database = ArchitecturePoC.DataAccess.Database;
using InvoiceProcessing = ArchitecturePoC.BusinessLogic.InvoiceProcessing;
public static Dictionary<Entities.Invoice, List<Entities.InvoiceLine>> GetAllInvoicesWithInvoiceLines()
{
Dictionary<Entities.Invoice, List<Entities.InvoiceLine>> result = new Dictionary<Entities.Invoice, List<Entities.InvoiceLine>>();
Database.InvoiceMapper invoiceMapper = new Database.InvoiceMapper();
Dictionary<Database.Entities.Invoice, List<Database.Entities.InvoiceLine>> invoicesWithInvoiceLines = invoiceMapper.GetAllInvoicesWithInvoiceLines();
foreach (KeyValuePair<Database.Entities.Invoice, List<Database.Entities.InvoiceLine>> invoiceWithInvoiceLines in invoicesWithInvoiceLines)
{
List<Entities.InvoiceLine> subResult = new List<Entities.InvoiceLine>();
foreach (Database.Entities.InvoiceLine invoiceLine in invoiceWithInvoiceLines.Value)
{
Entities.InvoiceLine resultInvoiceLine = new Entities.InvoiceLine();
resultInvoiceLine.InjectFrom(invoiceLine);
subResult.Add(resultInvoiceLine);
}
Entities.Invoice resultInvoice = new Entities.Invoice();
resultInvoice.InjectFrom(invoiceWithInvoiceLines.Key);
result.Add(resultInvoice, subResult);
}
return result;
}
この「きれいな分離」を、最終的には必要以上に心配するものと間違えているのではないかと心配しています。ファサードが急速に大きくなり、保守が困難になることは容易に想像できます。この複雑さを軽減するための提案はありますか?
補足: 興味深いドメイン イベント パターンを見てきましたが、この状況に適用する方法がわかりません。