DDD - 实体状态转换 [英] DDD - Entity state transition

查看:298
本文介绍了DDD - 实体状态转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下简化示例:

public class Ticket
{
   public int Id;
   public TicketState State;

   public Ticket()
   {
      // from where do I get the "New" state entity here? with its id and name
      State = State.New;
   }

   public void Finished()
   {
      // from where do I get the "Finished" state entity here? with its id and name          
      State = State.Finished;
   }
}

public class TicketState
{
   public int Id;
   public string Name;
}

类状态直接在域对象票证中使用。稍后在票的生命周期中,可能会设置其他状态。

The class state is used directly within the domain object ticket. Later in the ticket s lifecycle other states might be set.

票证持有到Ticket表以及TicketState中。所以在数据库中,票证将有一个外键到票状态表。

The ticket is persisted into a Ticket table, as well as the TicketState. So within the DB the ticket will have a foreign key to the ticket state table.

在实体中设置适当的状态时,如何从DB加载状态实例?我必须向实体注入一个存储库吗?我需要使用像城堡这样的框架吗?或者有更好的解决方案,也许从外面传递状态?

When setting the appropiate state within my entity, how do I load the state instance from the DB? Do I have to inject a repository into the entity? Do I need to use a framework like castle for such case? Or are there better solutions, maybe passing the state from outside?

public class Ticket
{
   //...
   public ITicketStateRepository stateRep; //<-- inject

   public Ticket()
   {
      State = stateRep.GetById(NEW_STATE_ID);
   }
   //...
}

是否任何最佳做法?到目前为止,我没有使用任何依赖注入框架或任何东西,并将任何持久性的东西从我的域中保留。

Is there any best practice? So far I did not use any dependency injection framework or anything and kept any persistence things out of my domain..

另一个意见:

public class Ticket
{
   //...

   public Ticket(NewTicketState newTicketState)
   {
      State = newTicketState;
   }
   public void Finished(FinishedTicketState finishedTicketState)
   {
      State = finishedTicketState;
   }
   //...
}


推荐答案

票证不会有对存储库的引用。它将与TicketState具有一对一的关系,TicketRepository将简单地执行JOIN并将值映射到Ticket中。

The Ticket would not have a reference to a repository. It would have a one-to-one relationship with TicketState, and the TicketRepository would simply do the JOIN and map the values into the Ticket.

当我创建模型对象I通常不会让他们知道它们是否持久,所以它们不会注入存储库。存储库处理所有CRUD操作。

When I create model objects I usually don't make them aware of whether or not they're persistent, so they aren't injected with a repository. The repository handles all CRUD operations.

有些人反对这一点,说它导致了一个贫血域模型;也许你是其中之一。如果是这样,请将存储库注入到Ticket对象中,但是简单的要求它执行JOIN并返回一个状态填充的Ticket。当您插入或更新时,您必须将两个表修改为单个工作单元,因此请务必打开事务。

Some people object to this, saying that it leads to an anemic domain model; perhaps you're one of them. If that's the case, inject the repository into your Ticket object, but simple ask it to do the JOIN and return a Ticket with its state populated. When you insert or update you have to modify two tables as a single unit of work, so be sure to have transactions turned on.

我喜欢CRUD操作的原因域模型对象之外的是它通常不是参与用例或事务的唯一域对象。例如,也许你简单的买票用例会有一个Ticket对象,但也可能还有一些其他的对象可以处理预留和座位以及总帐和行李库存以及各种各样的事情。您真的想要将多个模型对象作为单个工作单元。只有服务层可以知道模型对象何时采取自己的行动,何时是更大更大的计划的一部分。

The reason I like to have CRUD ops outside the domain model object is that it usually isn't the only domain object participating in a use case or transaction. For example, maybe your simple "buy ticket" use case will have a Ticket object, but there might also have to be some other objects that deal with reservations and seating and general ledger and inventory of baggage and all sorts of other things. You'll really want to persist several model objects as a single unit of work. Only the service tier can know when a model object is acting on its own and when it's part of a larger, grander plan.

更新:

我不喜欢用DAO注入模型对象的想法的另一个原因是它可以处理持久性职责是层次的浪费和引入的循环依赖。如果保持模型清除任何对持久化类的引用,您可以使用它们,而无需调用其他图层。这是一个单向依赖;持久性知道模型,但模型不知道持久性。

Another reason why I don't like the idea of injecting a model object with a DAO so it can handle persistence duties is the trashing of layers and the cyclic dependency it introduces. If you keep model clean from any references to persistence classes you can use them without having to invoke the other layer. It's a one-way dependency; persistence knows about model, but model does not know about persistence.

将持久性注入模型,它们是循环依赖的。你不能使用或测试任何一个没有另一个。没有分层,没有分离关注。

Inject the persistence into model and they're cyclicly dependent on each other. You can never use or test either one without the other. No layering, no separation of concerns.

这篇关于DDD - 实体状态转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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