标签: domain-driven-design

Localization in DDD

I have a list of physics parameters (like Pressure, Voltage and etc.) accessible to all users from all tenants (multi-tenant application). Now, I need a way to display appropriate language to different users.

Parameter is an aggregate root:

class Parameter
{
    public string Name { get; }
    public string Description { get; }
}
Run Code Online (Sandbox Code Playgroud)

I need a way to localize both name and description. My first approach was this:

class Parameter
{
    public IDictionary<Locale, NameAndDescription> Info { get; }
} …
Run Code Online (Sandbox Code Playgroud)

domain-driven-design localization

1
推荐指数
1
解决办法
1170
查看次数

CQRS 解决了哪些持久性问题?

我读过一些与此相关的帖子,但我仍然不太明白它是如何工作的。

举例来说,我正在构建一个像 Stack Overflow 这样的网站,有两个页面 => 一个列出所有问题,另一个页面供您提出/编辑问题。一个简单的、基于 CRUD 的 Web 应用程序。

如果我使用 CQRS,我将拥有一个单独的读/写系统、单独的数据库等......太棒了。

现在,我的问题是如何更新读取状态(毕竟在它自己的数据库中)。

我认为流程是这样的:

WebApp => User submits question WebApp => System raises 'Write' event WriteSystem => 'Write' event is picked up and saves to 'WriteDb' WriteSystem => 'UpdateState' event raised ReadSystem => 'UpdateState' event is picked up ReadSystem => System updates it's own state ('ReadDb') WebApp => Index page reads data from 'Read' system

假设这是正确的,这与从同一数据库读取/写入的 CRUD 系统有何显着不同?抛开 CQRS 的优点(例如单独的读/写系统扩展、重建状态、域边界分离等),从持久性的角度来看,可以解决哪些问题?避免了锁争用?

我可以通过使用队列在多线程 Web …

domain-driven-design read-write cqrs

1
推荐指数
1
解决办法
1854
查看次数

使用或不使用带有 ORM 的存储库

有很多声音说,在这个 ORM 时代,不再需要存储库。最近我自己也在思考这个问题,他们的论点对我来说通常是有道理的。

在我使用 EF Core 的新项目中,我想尝试使用无存储库方法来使事情变得更加直接和简单。毕竟,简单总是好的。

事情进展得很顺利,直到我意识到我经常写这样的东西(这不是真正的聚合,只是一个人为的例子):

ctx.Invoices.Include(x => x.User).ThenInclude(x => x.Address).Include(x => x.Items).FirstOrDefault(x => x.Id == id);
Run Code Online (Sandbox Code Playgroud)

好吧,所以每次我需要得到一个汇总时,我都需要写这个声明,并且有机会,有时/有人会忘记包含重要的参考文献。

将这段代码放入辅助类中怎么样?

class InvoiceHelper
{
  public Invoice FindById(int id) {...}
}
Run Code Online (Sandbox Code Playgroud)

这不是变相的存储库的开始吗?因此,即使使用 ORM,我仍然发现存储库很有用。

其他人如何做这些事情并且在没有存储库的情况下仍然感到高兴?

一些讨论无存储库方法的文章:

c# orm domain-driven-design entity-framework ddd-repositories

1
推荐指数
1
解决办法
672
查看次数

在哪一层中度量收集被认为适合领域驱动设计?

我需要从我的域收集和导出指标。在某种程度上,我觉得指标是纯粹基于业务的,因此必须位于领域层。另一方面,我害怕将计数器的状态存储在域中,因为它们的正确状态取决于事务性

想象一下,您有一个典型的 CRUD + 一些次要业务逻辑 DDD 应用程序,并且您想要注册所有创建、更新等,然后通过端点导出它们。你会如何设计这个?

architecture design-patterns domain-driven-design

1
推荐指数
1
解决办法
541
查看次数

如何从 AxonFramework 或任何其他事件溯源框架中的数据库加载聚合对象?

我有这个问题很久了。对于 Internet 上的大多数示例。他们总是先创建一个聚合对象,然后再操作聚合对象。我的问题是,除了每次都创建一个之外,如何从数据库加载一个。我将以 e-sopping 为例。我将一种产品视为一个聚合对象。我无法将它们全部加载到我的程序内存中。那我该怎么办呢?

我所做的是,编写另一个带有参数 UpdateProductCommand 的构造函数以及带有参数 CreateProductCommand 的构造函数。在此构造函数中,我从数据库加载它。这样可以吗?

class Product{

    public Product(){}

    @CommandHandler
    public Product(CreateProductCommand command){
        apply(new CreateProductEvent(command.id));
    }

    @CommandHandler
    public Product(UpdateProductCommand command){
        load(command.id)
        ...
        apply(new UpdateProductEvent(command.id));
    }
}
Run Code Online (Sandbox Code Playgroud)

frameworks domain-driven-design event-sourcing axon

1
推荐指数
1
解决办法
425
查看次数

在 MasstTransit 中发送、发布和请求/响应

最近我尝试在我们的微服务生态系统中使用MassTransit

根据 MassTransit 词汇和文档,我的理解是:

  • 发布:向 1 个或多个订阅者发送消息(发布/订阅模式)以传播消息。
  • Send:用于像发布一样以一劳永逸的方式发送消息,但它仅用于一个接收者。与发布的主要区别在于,在发送中如果您的目的地没有收到消息,它将返回异常。
  • 请求:使用请求/回复模式仅发送消息并在不同的通道中获取响应,以便能够从接收者获取响应值。

现在,我的问题是根据微服务的理念,遵循事件驱动的设计,我们使用Publish将消息(事件)传播到整个生态系统。但这里的Send到底有什么用法(用例)呢?只是为了在接收者不存在时获得异常?

我的下一个问题是,在微服务生态系统中同时使用PublishSendRequests是一种好方法吗?例如发布传播事件、发送命令(即发即忘)以及从目的地获取响应的请求。

----- 更新 我还发现克里斯·帕特森在这里澄清了很多事情。这对我也有很大帮助。

domain-driven-design masstransit event-driven-design microservices

1
推荐指数
1
解决办法
4603
查看次数

DDD应用层和持久化事务

DDD 的领导者将应用层视为事务管理的适当位置。例如,来自文斯·沃恩:

应用程序服务驻留在应用程序层。[...]。他们可以控制持久性事务[...]”。

这是否不会将基础设施问题泄漏到应用程序层中,因为持久性(更具体地说,其实现细节)不是应用程序层应该意识到的事情?

虽然我可以在应用程序层中定义一个契约来满足基础设施层的具体要求,但这仍然感觉有点像泄漏实现细节。虽然这确实实现了与实际持久性具体的解耦,但我认为它并不会使应用程序层真正忽略持久性实现细节。这难道不是我应该关心的事情吗?

下面是一个伪 PHP 的示例,展示了它的外观:

namespace Acme\Application\Contracts;

// A contract in the Application Layer to be satisfied by an infrastructure implementation
interface TransactionManager {
    public function begin() : void;
    public function commit() : void;
    public function rollBack() : void;
}

namespace Acme\Intrastructure\PDO;

class PDOTransactionManager implements TransactionManager {
   private PDO $pdo;

   public function begin() : void {
      $this->pdo->beginTransaction();
   }

   // ...
}

namespace Acme\Application\Modules\Ordering;

// A context agnostic application service
final …
Run Code Online (Sandbox Code Playgroud)

architecture design-patterns domain-driven-design onion-architecture

1
推荐指数
1
解决办法
1106
查看次数

使用 Kafka 和每个实体类型的主题进行事件溯源,外键会发生什么情况?

我正在尝试使用 Kafka 设计一个事件源系统。假设我们有一个非常简单的事件源应用程序,由四个聚合根组成:用户、类别、产品和购买。

遵循confluence的一些指导,我创建了 4 个主题(为简单起见,我们假设每个主题 1 个分区),每个聚合一个:

  • 为用户提供一个主题
  • 类别的一个主题
  • 产品的一个主题
  • 购买的一个主题

我的投影是 PostgresSQL 投影,它从 Kafka 读取事件,然后将每个事件转换为 SQL 查询(根据事件类型插入、更新或删除)。

问题是数据库模型大约是这样的:

在此输入图像描述

鉴于主题之间的事件顺序无法保证,如果我尝试将产品添加到没有其类别的数据库中,我很可能会收到来自数据库的foreignkey错误。同样,如果我尝试在用户或产品尚未处理的情况下添加购买,我很可能会收到另一个外键错误。

我必须使用哪些分区选项来解决读取模型中的外键问题,并允许我的系统随着更多实体和更多事件而增长,而不必依赖将所有内容放入单个主题来避免外键问题?

我想到的一件事是,虽然我可以独立处理用户和产品而不会发生冲突,但我仍然需要对购买做一些事情(以某种方式延迟该主题的事件处理,直到确保用户和产品存在于数据库)。

domain-driven-design event-sourcing apache-kafka

1
推荐指数
1
解决办法
566
查看次数

返回与异常

我正在使用 DDD 和六边形架构在 Typescript 中做一个应用程序,我想知道在哪些情况下我应该在验证中返回 false,以及在哪些情况下我应该抛出异常。

据我所知,当您没有处理该错误时,就会引发异常,您不会期望发生这种情况,但后来我看到更好的程序员也使用 DDD 编写代码,并且他们正在使用未找到异常,显然你应该处理这个问题。

在我的示例中,我想在 valueObject 中进行验证,如下所示:

public static nameValidation(name: string): boolean {
    if (Name.containsSpecialChars(name)) {
      return false;
    }
    if (name.length < 2) {
      return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我把它作为一个布尔值,在验证不正确的情况下返回 false,但可以很容易地将其更改为异常。

我真的不知道如何区分哪个必须去哪里。

有什么想法吗?

domain-driven-design typescript

1
推荐指数
1
解决办法
704
查看次数

DDD最好的ORM是什么?

我更喜欢商业解决方案.所以不是NHibernate.现在我正在玩LLBLGen pro,我喜欢它,但它似乎不是DDD友好的.

.net architecture orm domain-driven-design llblgenpro

0
推荐指数
1
解决办法
1693
查看次数