ドメイン駆動設計に最適な 5 つのツール
開発者として、私たちはドメイン モデルに沿ってビジネス要件を満たすソフトウェア システムを構築したいと思うことがよくあります。そこで DDD が登場します。
ドメイン駆動設計 (DDD) は、ドメイン モデルと実装の調整に重点を置くソフトウェア システム開発方法論です。問題領域に焦点を当て、関連する概念と関係についての共通の理解を構築することで、開発者は利害関係者のニーズをより適切に反映し、変化するビジネス要件により適応できるソフトウェアを作成できます。
DDD をサポートするために、開発者はドメイン モデリング、データ マッピング、テストなどのタスクに役立つさまざまなツールやテクノロジを使用できます。この記事では、DDD をサポートするために利用できる最良のツールとフレームワークのいくつかを検討します。イベント ソーシングや CQRS からドメイン モデリング ツールや ORM フレームワークまで、さまざまなツールを取り上げ、その主な利点と使用例に焦点を当てます。DDD を初めて使用する場合でも、経験豊富な実践者であっても、ドメイン駆動型ソフトウェア システムを構築するための最適なツールを見つけるために読み続けてください。
ドメイン モデルとは何ですか?また、それをどのように使用できますか?
まず購入してください。DD を初めて使用する場合は、部屋の中のピンクの象にすぐに対処しましょう。「ドメイン モデル」とは何ですか?
ドメイン モデルはドメイン駆動設計 (DDD) の中心的な概念であり、ソフトウェア システムの中核を表します。これは、ソフトウェア システムが対処することになる現実世界の領域の概念モデルであり、データの構造とシステムの動作を定義します。ドメイン モデルは、ビジネス専門家、開発者、ユーザーを含むすべての関係者の間で問題ドメインについての共通の理解を得るものです。
このモデルは次のもので構成されます。
- エンティティ。ライフサイクルを持つ一意の ID を持つオブジェクトです。
- 集約。トランザクションの整合性境界を形成する関連オブジェクトのクラスターです。
- 値オブジェクトは、一意の ID を持たず、そのプロパティによって定義されるオブジェクトです。
- ドメイン サービスは、単一のエンティティまたは値オブジェクトに固有ではない操作またはアルゴリズムです。
例を考えてみましょう
私は、複雑な概念を理解するために常に実践的な例を使用することを好みます。そのため、e コマース プラットフォームを構築しているとします。その要件の 1 つは、ユーザーが製品を注文できるようにすることです。
ドメイン駆動設計では、問題ドメイン内の関連する概念と関係を表すドメイン モデルを作成することから始めます。
このドメインの主要なエンティティの 1 つは、ユーザーが行った個々の注文を表す Order エンティティです。Order エンティティには、OrderID、CustomerID、注文された製品のリスト、合計価格、ステータス(保留中、履行済み、キャンセルなど) などのプロパティがあります。
このドメインの別のエンティティは、購入可能な製品を表す Product エンティティである可能性があります。Product エンティティには、 ProductID、名前、説明、画像、価格、カテゴリのリストなどのプロパティが含まれる場合があります。
集計は、トランザクションの整合性境界を形成する関連オブジェクトのクラスターであるため、Product エンティティや Customer エンティティなどの関連エンティティとともに、Order エンティティを含む Order 集計を作成する場合があります。これにより、これらのエンティティに対する変更がトランザクション的に一貫した方法で実行されることが保証されます。
また、一意の ID を持たないがプロパティによって定義される、配送先住所や請求先住所などの概念を表す値オブジェクトを作成することもあります。
最後に、配送料を計算し、適切な配送情報で Order エンティティを更新する役割を持つ ShippingService のようなドメイン サービスを作成する場合があります。
全体として、このドメイン モデルは、問題ドメインの主要な概念と関係を理解するのに役立ち、電子商取引プラットフォームを実装するための基盤を提供します。実装をドメイン モデルに合わせて調整することで、より柔軟で保守しやすく、変化するビジネス要件に対応できるシステムを作成できます。
それでは、それを行うのに役立ついくつかのツールを見てみましょう。
イベントソーシング — DDD の聖杯
イベント ソーシングは、集約、エンティティ、値オブジェクトなどの DDD 概念を実装するために使用される手法です。イベント ソーシングでは、システムの現在の状態を単に保存するのではなく、システムに加えられたすべての変更を一連のイベントとして保存します。そうすることで、いつでもシステムの状態を再構築できるため、非常に強力です。ソフトウェアのタイムマシンを持っているようなものです。
電子商取引プラットフォームの例を続けてみましょう。
Order エンティティへの変更を時間の経過とともに追跡したいとします。イベント ソーシングでは、Order エンティティを直接更新する代わりに、Order の状態変化を表す一連のイベントを作成します。各イベントは、Order エンティティの状態に対する個別の変化を表し、イベント ログに保存されます。
たとえば、ユーザーが製品を注文したとします。新しい注文の詳細で Order エンティティを直接更新する代わりに、OrderID、CustomerID、注文された製品のリスト、および合計価格を含む OrderPlaced イベントを作成します。次に、このイベントをイベント ログに追加します。
その後、ユーザーが製品を追加または削除して注文を更新すると、OrderID と更新された製品リストを含む OrderUpdated イベントが作成され、イベント ログに追加されます。注文がキャンセルされた場合は、OrderID とキャンセルの理由を含む OrderCanceled イベントを作成し、イベント ログに追加します。
イベント ソーシングを使用すると、イベント ログ内のイベントを再生することで、いつでも Order エンティティの状態を再作成できます。イベント ログを使用して、Order エンティティへの変更を監査したり、注文の履歴を示すレポートを作成したりすることもできます。
イベント ソーシングを使用してこれらのオブジェクトの状態変化をキャプチャすることで、ソフトウェア実装がドメイン モデルと確実に一致するようにすることができます。
たとえば、Order が実際には 1 つ以上の OrderLine エンティティと ShippingAddress 値オブジェクトで構成される集約であるとします。イベント ソーシングを使用すると、OrderPlaced、OrderUpdated、OrderCanceled などの一連のイベントとして Order 集合体に対する各状態の変化をキャプチャできます。これらのイベントを使用して、いつでも注文集合体の状態を再作成できるため、ソフトウェア実装がドメイン モデルを正確に反映していることが保証されます。
Bitを使用すると、イベント ストア、イベント ハンドラー、その他の関連コンポーネントなど、イベント ソーシングの実装をカプセル化するコンポーネントを作成できます。このビットは他のチームと共有できるため、チームは自分のプロジェクトで簡単に再利用できます。これに Bit を使用すると、さまざまなプロジェクトやチーム間で実装の一貫性を確保できます。これは、複数の開発チームが異なるプロジェクトに取り組んでいる大規模な組織で特に価値があります。
CQRS — 1 つのサイズではすべてに適合しない場合
CQRS (Command Query Responsibility Segregation) は、システム内の読み取り操作と書き込み操作を分離するために使用されるパターンです。従来のアーキテクチャでは、読み取りと書き込みの両方を処理する単一のモデルがあり、これがパフォーマンスの問題やスケーラビリティの問題を引き起こす可能性があります。CQRS は、読み取りモデルと書き込みモデルを分離することでこの問題を解決し、各モデルを個別に最適化できるようにします。
CQRS をサポートするために、いくつかのフレームワークが利用可能です。そのようなフレームワークの 1 つが NestJS です。NestJS は、組み込みイベント バスを使用して CQRS を実現します。これにより、アプリケーションのさまざまな部分にわたってイベントをパブリッシュおよびサブスクライブできます。これにより、アプリケーションのデータベースに書き込むコマンド ハンドラーや、データベースからデータを取得してクライアントに返すクエリ ハンドラーの実装が簡単になります。
これら 2 つの役割を分離することで、アプリケーションのパフォーマンスが向上し、テストが容易になり、変更に対する耐性が向上します。
NestJS とBitを使用すると、DDD アプリケーションの開発能力をさらに強化できます。Bit は、さまざまなプロジェクト間でコード コンポーネントを共有および再利用する方法を提供し (これについて詳しくは、この記事をお読みください)、チームがより効果的にコラボレーションし、作業の重複を避けることができます。 コマンド ハンドラーやクエリ ハンドラーなどの NestJS コンポーネントの共有ライブラリを作成すると、アプリケーション ポートフォリオ全体で記述および保守する必要があるコードの量を削減できます。さらに、Bit を使用すると、コンポーネントのバージョンを管理し、長期にわたって変更を追跡できるため、依存関係の管理が容易になり、アプリケーション間の互換性が確保されます。
ドメイン モデリング ツール — ドメイン モデルを視覚化する
ああ、ドメイン モデリング ツールですね。ドメイン駆動設計 (DDD) に興味がある場合は、おそらくよく知っているでしょう。そうでない場合でも、心配する必要はありません。私がここであなたがスピードを出せるようにお手伝いします。
では、ドメイン モデリング ツールとは何でしょうか? 一言で言えば、これらは開発者がソフトウェア システムのドメイン モデルを作成および視覚化するのに役立つソフトウェア アプリケーションです。ドメイン モデルは、ソフトウェア システムがモデル化するように設計されている現実世界の概念と関係を表現したものです。これは DDD の重要な部分であり、すべての関係者間でドメイン モデルを明確かつ簡潔に共有することの重要性が強調されます。
ソフトウェア システムのドメイン モデルの作成と視覚化に役立つさまざまなドメイン モデリング ツールが利用可能です。これらのツールは、ドメイン モデルが正確でよく理解されていることを確認するためにドメインの専門家や他のチーム メンバーと協力する場合に特に役立ちます。
このようなツールの一例としてPlantUMLがあります。これは、単純な構文を使用して、クラス図、シーケンス図、ユースケース図などを含む UML 図を作成できるテキストベースの図作成ツールです。PlantUML はオープンソースで、PNG、SVG、PDF などの複数の出力形式をサポートしています。拡張機能やプラグインを通じて、Visual Studio Code を含むさまざまなエディターや IDE と統合できます。
もう 1 つの人気のあるツールはLucidchartです。これは、ドラッグ アンド ドロップ インターフェイスを使用して、フローチャート、UML 図、ER 図などを含むさまざまな種類の図を作成できる Web ベースの図作成ツールです。Lucidchart はさまざまなテンプレートと図形を提供しており、プロフェッショナルな外観の図を簡単にすばやく作成できます。
さらに、IntelliJ IDEA などの一部のコード エディターや IDE では、UML 図やその他のビジュアル モデリング ツールのサポートが組み込まれており、複雑なドメイン モデルを持つソフトウェア システムで作業する場合に役立ちます。
全体として、ドメイン モデリング ツールは、複雑なドメイン モデルを含むソフトウェア システムで作業する場合に貴重な資産となります。これらは、ドメイン モデルを作成、視覚化し、他のチーム メンバーと効果的に伝達するのに役立ち、ビジネス要件に合わせたソフトウェア システムの構築を容易にします。
ORM (オブジェクト リレーショナル マッピング) フレームワーク
DDD 実装の主な課題の 1 つは、オブジェクトをリレーショナル データベースにマッピングすることです。ここで ORM フレームワークが役に立ちます。ORM フレームワークは、オブジェクトをリレーショナル データベース内のテーブルにマップする方法を提供します。これにより、フレームワークがデータベースとのやり取りを処理しながら、コード内でオブジェクトを操作できるようになります。
すべての言語に共通の ORM フレームワークが多数あります。JavaScript エコシステムの場合、他に方法がないため、選択肢はたくさんあります。とはいえ、最も人気のあるオプションのいくつかはSequelizeとPrismaです。これらのフレームワークは、オブジェクトをデータベース内のテーブルにマップする方法を提供し、オブジェクト指向構文を使用してデータベースにクエリを実行する方法も提供します。
ORM フレームワークを使用する利点の 1 つは、記述しなければならない定型コードの量が削減されることです。また、コードを変更することなく、基礎となるデータベース スキーマを簡単に変更できるようになります。
ただし、ORM フレームワークではパフォーマンスのオーバーヘッドが発生し、複雑なクエリ (複雑な JOIN やサブクエリなど) の実行が困難になる可能性があるため、アプリケーションに適切なフレームワークを選択することが重要です。
ORM によって追加されるすべての利点に加えて、Bit では、データ構造を簡単に共有する複数のプロジェクト間でデータ モデルと汎用コードを再利用できるため、さらに多くの価値が追加されます。たとえば、特定のデータ モデルを定義する ORM コンポーネントを作成し、それをアプリケーションのさまざまな部分で再利用できます。これにより、同じコードを何度も記述する必要がなくなるため、時間と労力を節約できます。さらに、Bit を使用するとコンポーネントの管理とバージョン管理が簡単にできるため、すべてのコンポーネントが最新であり、データ構造の現在のバージョンに対応していることを確認できます。
読んだ内容は気に入りましたか? 私の無料ニュースレターの購読をご検討ください。IT 業界における私の 20 年分の知恵を皆さんと共有しています。「老開発者のとりとめのない話」に参加してください!
テストフレームワーク
ドメイン駆動設計 (DDD) でのテストに関しては、ドメイン モデルが正しく、期待どおりに動作することを確認することが重要です。ここでテスト フレームワークが登場します。ソフトウェアの最終ロジックが期待を確実に満たすように、テストでは何らかの方法でドメイン モデルを記述する必要があります。
JavaScript で使用できるテスト フレームワークは多数あり、それぞれに独自の長所と短所があります。
JavaScript の 2 つの非常に人気のあるテスト フレームワークは、Jest と Mocha です。
Jest は、Facebook によって構築された JavaScript テスト フレームワークです。シンプルで直感的なテスト API を提供するため、JavaScript コードのテストを簡単に作成できます。Jest は、より効率的で効果的なテストを作成するのに役立つモックやスナップショット テストなどの機能も提供します。
Mochaは、好みのスタイルでテストを作成できる JavaScript テスト フレームワークです。同期コードと非同期コードの両方をテストするために使用できる柔軟な API を提供します。Mocha は複数のレポート形式もサポートしているため、テスト ワークフロー内の他のツールと簡単に統合できます。
Jest や Mocha などのテスト フレームワークを使用すると、バグを発見し、ドメイン モデルが期待どおりに動作していることを確認できます。ただし、テストを設定して常に実行するようにするには、時間がかかり、面倒な作業になる可能性があります。ここでビットが役立ちます。
Bit は、作成するコンポーネントごとにテスト テンプレートを自動的に生成します。それだけでなく、テスト手順はすべての主要プロセス (コンポーネントのタグ付けやビルドなど) 内で必須であるため、たとえそうしたくない場合でも、コンポーネントが確実にプッシュされ、確実にプッシュされるようにテストを作成する必要があります。他の開発者と共有されます。さらに、Jest (または必要なテスト フレームワーク) のセットアップは Bit によって自動的に行われるため、そのステップについて心配する必要もありません。
結論として、ドメイン駆動設計 (DDD) 原則を使用してアプリケーションを開発する場合、テスト フレームワークを使用することが重要です。Jest と Mocha はどちらも JavaScript アプリケーションをテストするための一般的な選択肢であり、Bit を使用するとテスト プロセスを合理化できます。これにより、時間と労力を節約し、テストが最新で正しく動作することを保証できます。
要約すると、ドメイン駆動設計 (DDD) は、ドメイン モデルと実装の調整に焦点を当てた、ソフトウェア システムを開発するための強力な方法論です。DDD をサポートするには、イベント ソーシング、CQRS、ドメイン モデリング ツール、ORM フレームワーク、テスト フレームワークなど、さまざまなツールとテクノロジを使用できます。
さらに、Bit を使用すると、チームは特定のビジネス機能をカプセル化するコンポーネントを作成および共有できます。これは、DDD に依存する複雑なアプリケーションを構築および保守するために重要です。コンポーネントを使用して、ドメイン モデルを構築し、データベースと統合し、複雑なビジネス ロジックを実行できます。
したがって、DDD を始めたばかりであっても、熟練したプロであっても、これらのツールとテクノロジは、ビジネス ニーズに合わせたより優れたソフトウェア アプリケーションを構築するのに役立ちます。
さあ、試してみて、何が自分にとって最も効果的かを見つけてください!