4
永続性は純粋に機能的な言語にどのように適合しますか?
コマンドハンドラーを使用して永続性を処理するパターンは、IO関連のコードをできるだけ薄くしたい純粋に機能的な言語にどのように適合しますか? オブジェクト指向言語でドメイン駆動設計を実装する場合、コマンド/ハンドラーパターンを使用して状態の変更を実行するのが一般的です。この設計では、コマンドハンドラーはドメインオブジェクトの上に配置され、リポジトリの使用やドメインイベントの発行など、永続性に関連する退屈なロジックを担当します。ハンドラーは、ドメインモデルのパブリックフェイスです。UIなどのアプリケーションコードは、ドメインオブジェクトの状態を変更する必要があるときにハンドラーを呼び出します。 C#のスケッチ: public class DiscardDraftDocumentCommandHandler : CommandHandler<DiscardDraftDocument> { IDraftDocumentRepository _repo; IEventPublisher _publisher; public DiscardDraftCommandHandler(IDraftDocumentRepository repo, IEventPublisher publisher) { _repo = repo; _publisher = publisher; } public override void Handle(DiscardDraftDocument command) { var document = _repo.Get(command.DocumentId); document.Discard(command.UserId); _publisher.Publish(document.NewEvents); } } documentドメインオブジェクトは、((「あなたは既に破棄されていた文書を破棄することはできません」または「ユーザーが文書を破棄する権限を持つべきである」のような)ビジネスルールを実装するため、我々は公開する必要があるドメインイベントを発生させるための責任があるdocument.NewEventsだろうIEnumerable<Event>おそらく含まれていますDocumentDiscarded)イベントを。 これは素晴らしいデザインです-拡張が簡単で(ドメインモデルを変更せずに新しいコマンドハンドラーを追加することで新しいユースケースを追加できます)、オブジェクトの永続化方法に依存しません(MongoのNHibernateリポジトリを簡単に交換できます)リポジトリ、またはRabbitMQパブリッシャーをEventStoreパブリッシャーに交換します)これにより、偽物やモックを使用して簡単にテストできます。また、モデル/ビューの分離に従います-コマンドハンドラーは、バッチジョブ、GUI、またはREST APIのいずれで使用されているかわかりません。 Haskellのような純粋に機能的な言語では、おおよそ次のようにコマンドハンドラーをモデル化できます。 newtype CommandHandler = CommandHandler {handleCommand :: …