Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 如何处理域模型的持久性?_Oop_Domain Driven Design_Persistence - Fatal编程技术网

Oop 如何处理域模型的持久性?

Oop 如何处理域模型的持久性?,oop,domain-driven-design,persistence,Oop,Domain Driven Design,Persistence,既然域模型应该是普通对象,那么如何处理持久性呢? 我的理解是,所有持久化都必须在应用层中进行,但是域模型如何通知应用层需要进行的任何CRUD操作,然后将它们传递到存储库 有什么建议吗?域不会通知应用层CRUD操作。它不知道应该如何或何时持久化域对象。应用程序层决定何时结束给定的应用程序事务并刷新对持久存储的更改。是您正在寻找的概念 域服务被注入到实体/域对象中。域对象通过接口调用服务 编辑:这个例子是C#,因为它是我的母语。如果您的语言支持“”,则可以在此处应用这些概念 public class

既然域模型应该是普通对象,那么如何处理持久性呢? 我的理解是,所有持久化都必须在应用层中进行,但是域模型如何通知应用层需要进行的任何CRUD操作,然后将它们传递到存储库


有什么建议吗?

域不会通知应用层CRUD操作。它不知道应该如何或何时持久化域对象。应用程序层决定何时结束给定的应用程序事务并刷新对持久存储的更改。

是您正在寻找的概念

域服务被注入到实体/域对象中。域对象通过接口调用服务

编辑:这个例子是C#,因为它是我的母语。如果您的语言支持“”,则可以在此处应用这些概念

public class Program
{
    public static void Main()
    {
        Order myOrder = new Order(new OrderRepository());

        myOrder.Save();
    }
}

public interface IOrderRepository
{
    void Save(Order order);
}

public class OrderRepository : IOrderRepository
{
    public void Save(Order order)
    {
          // Persistence stuff here
    }
}

public class Order
{
    private IOrderRepository _orderRepository;
    public Order(IOrderRepository orderRepository)
    {
        _orderRepository = orderRepository;
    }

    public void Save()
    {
        _orderRepository.Save(this);
    }
}

应用程序的职责是协调域中的操作。对象包含逻辑和业务规则,但它不知道应用程序的所有流量。满足应用程序需求所需的步骤数保留在应用程序层中。存储库处理持久性,但它是调用持久性的应用程序

例如:

Customer customer = customerRepository.GetById(2);
customer.Rename("Jhon Doe");
customerRepository.Save(customer);

域对象被传递到处理持久性问题的存储库。感谢plalx,这就是我在当前项目中所做的。当我不得不决定如何实施DDD时。。。我总觉得我做错了。好吧,搜索一下“DDD战术模式”,怀疑是什么会让你进步;)DDD本身与持久性无关。从域的角度来看,持久性只是存储库。让实体知道持久性细节是违反DDD核心原则的。应用程序服务负责与存储库交互,实体不应该知道它。@plalx:只要实体通过接口访问服务,实体就可以知道应用程序服务。订单实体有一个“保存”方法,因为“保存订单”是一个域命令。订单的保存方式取决于服务的实现,服务只与实体松散耦合。这是一种标准的依赖项注入技术。当然,不应该将DB访问代码放在实体中。我看不出这是如何“违背DDD核心原则”的。请具体说明您的意思。@plalx:另外,您关于实体“了解持久性详细信息”的评论是不正确的。在我的示例中,实体不知道持久性细节,因为它只通过接口访问存储库。实体只知道“什么”,而不知道“如何”,即使实体委托给存储库,但它有一个
save
方法这一事实泄露了持久性知识。
save
操作对业务没有任何意义,它不是一个业务术语或流程,只是一个持久性问题。域模型应该仅用构成泛在语言的业务术语来表示。DDD不仅仅是关于正确完成OO,它是关于将业务专家的想法反映到代码中。一般来说,依赖项注入没有错,但是DDD实体是一种非常特殊的对象,除了那些需要尊重初始不变量的对象之外,不应该有任何构造依赖项。然而,可以做的是在方法级别注入域服务,但在这些罕见的情况下,应该遵循ISP。你可以去看看,有很多关于DDD实体和依赖注入的文章,最有知识的DDD实践者,比如Vaughn Vernon,都反对实体的构造函数注入。