DDD-域模型,服务和存储库之间的依赖关系 [英] DDD - Dependencies between domain model, services and repositories

查看:318
本文介绍了DDD-域模型,服务和存储库之间的依赖关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是想知道其他人如何对他们的体系结构进行分层.说我的图层如下:

域层
-产品
--ProductService(imp应该进入这一层吗?)
--IProductService
--IProductRepository

基础设施层
--ProductRepository(我网域中的IProductRepository的Imp)

现在,当创建新产品时,我需要通过调用ProductService.GetNextProductId()方法来分配产品ID.

因为该服务对存储库有依赖性,所以我使用IProductRepository接口设置了ProductService ctor,该接口可以在以后注入.像这样的东西:

    public class ProductService : IProductService
    {
        private IProductRepository _repository;

        public ProductService(IProductRepository repository)
        {
            _repository = repository;
        }

        public long GetNextProductId()
        {
            return _repository.GetNextProductId();
        }
    }

我的问题是,当我在产品类中使用服务时,在实例化新的ProductService类时正在引用ctor中的存储库.在DDD中,要有这样的参考非常重要.我什至不确定我的产品域类是否已正确设置以调用该服务,有人可以建议吗?

public class Product : Entity
    {
        private ProductService _svc;
        private IProductRepository _repository;

        public Product(string name, Address address) //It doesnt seem right to put parm for IProductRepository in the ctor?
            : base(_svc.GetNextProductId) // This is where i pass the id
        {
            // where to create an instance of IProductRepository?
        }
    }

我该如何优雅地解决此设计问题?我愿意听取经验丰富的DDD'ers的建议

感谢您的评论.我也怀疑是否应该从产品类中调用该服务.我还没有使用工厂模式,因为对象的构造仍然很简单.我不认为这值得采用工厂方法吗?

我很困惑...如果我的Product类需要来自服务的其他一些数据,则将ProductId放在一边,例如GetSystemDateTime()(我知道,不好的例子,但试图演示非db调用),该服务方法在哪里?叫?

DDD中的服务是逻辑转储,其中逻辑对域对象不是自然的,对不对?那么它如何粘合在一起?

解决方案

最后一点,DDD中的服务是放置我所描述的笨拙"逻辑的地方.如果您有某种逻辑或工作流程依赖于其他实体,则这是通常不适合"域对象本身的逻辑类型.示例:如果我在业务对象上有一个方法可以执行某种类型的验证,则服务类可以执行此方法(仍将与实体相关的实际验证逻辑保留在其类内)

我经常提到的另一个非常好的例子是资金转帐方法.您不会将帐户对象从一个对象转移到另一个对象,但是您将拥有使用"to"帐户和"from"帐户的服务.然后在服务中,您将调用发件人"帐户上的提款方法,以及收款人"帐户上的存款方法.如果您尝试将其放入帐户实体本身,则会感到尴尬.

可以找到有关此主题深入讨论的出色播客Just wanted to know how others have layered their architecture. Say I have my layers as follows:

Domain Layer
--Product
--ProductService (Should the imp go into this layer?)
--IProductService
--IProductRepository

Infrastructure Layer
--ProductRepository (Imp of IProductRepository in my domain)

Now when a new product is created i have a requirement to assign a product id by calling into the ProductService.GetNextProductId() method.

Because the service has a dependency on the repository i set up the ProductService ctor with an interface of IProductRepository which can be injected later. something like this:

    public class ProductService : IProductService
    {
        private IProductRepository _repository;

        public ProductService(IProductRepository repository)
        {
            _repository = repository;
        }

        public long GetNextProductId()
        {
            return _repository.GetNextProductId();
        }
    }

My issue is that when i use the service in the Product Class i am making reference to the Repository in the ctor when instantiating a new ProductService class. In DDD its a big no no to have such a reference. I' am not even sure if my product domain class is being set up correctly to call the service, can someone pls advise:

public class Product : Entity
    {
        private ProductService _svc;
        private IProductRepository _repository;

        public Product(string name, Address address) //It doesnt seem right to put parm for IProductRepository in the ctor?
            : base(_svc.GetNextProductId) // This is where i pass the id
        {
            // where to create an instance of IProductRepository?
        }
    }

How can i elegantly solve this design issue? I am open to suggestions from experienced DDD'ers

EDIT:

Thanks for you comments. I also doubted if the service should be called from the Product Class. I have not used a factory pattern (yet) as the construction of the object is still simple. I dont feel it warrants a factory method yet?

I' am confused...Putting the ProductId aside if my Product class needed some other data from a Service e.g GetSystemDateTime() (i know, bad example but trying to demonstrate a non db call) where would this service method be called?

Services in DDD are logic dumps where the logic is not natrual to the domain object, right? So How does it glue together?

解决方案

To your last point, services in DDD are a place to put what I describe as "awkward" logic. If you have some type of logic or work flow that has dependencies on other entities this is the type of logic that usually doesn't "fit" inside a domain object itself. Example: If I have a method on my business object to perform some type of validation, the service class might execute this method (still keeping the actual validation logic related to the entity inside its class)

Another really good example I always mention is the funds transfer method. You wouldn't have an account object transfer from one object to another, but instead you would have a service that takes the "to" account and the "from" account. Then inside the service you would invoke the withdrawal method on your "from" account and the deposit method on your "to" account. If you tried to put this inside the account entity itself it would feel awkward.

A great podcast that talks in depth about this very topic can be found here. David Laribee does a really good job explaining now only the "how" but the "why" of DDD.

这篇关于DDD-域模型,服务和存储库之间的依赖关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆