首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >富域模型和容器服务

富域模型和容器服务
EN

Software Engineering用户
提问于 2014-04-08 21:46:04
回答 2查看 937关注 0票数 2

我在Java项目的编程方面有很长的经验,但正如我注意到的,我所做的大部分工作都是关于Transaction Script (Anti)模式的。

因此,我想学习使用富域模型,但是还有一个问题,域对象是否依赖于容器/系统服务(这样的持久性、邮件、.)?

我读过这篇文章,我一点也不同意!

  • 如何初始化服务并将其注入域实体?
  • 那么单一的责任模式呢?
  • 这不就是反对重用吗?

我也读过应用UML和模式精彩的书,但我不知道为什么作者不描述如何在定义数据访问层之后将责任分配给实体(见第38章)。

那么,拥有富域模型以及不依赖于容器/系统服务的最佳实践是什么呢?

例如,请考虑在软件中使用以下场景:

  • 有一些代理(与系统一起工作)
  • 我们代理商的业务是卖保险单。
  • 每一种保险单都有一种特殊类型的预印卡,由代理人发给被保险人。
  • 我们需要追踪每个探员可用卡的数量。
  • 因此有一个用例,它记录了每种类型的卡片给每个代理的数量。
  • 有一个用例,记录代理人损坏的每种类型的未使用卡片的数量。
  • 这些卡被用作代理商出售保险单的工具。

我相信建议我在agent类中使用如下方法:

代码语言:javascript
复制
class Agent {
    int computeRemainigCards(CardType cardType) {}
}

但是,代理只需依赖3个DAO类来承担一项责任:

  • 一种计算给代理的每一种卡片类型的计数之和。
  • 一种用来计算旧卡的计数(通过出售保险单)。
  • 一个用来计算损坏的未售出卡片的总和。

我相信这会使域名实体变得一团糟。那么好的做法是什么呢?

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2014-04-14 10:11:44

您的问题正是通过阅读领域驱动设计回答的问题。

安迪的评论是对的。实体不依赖于DAOs。它们依赖于表示实体需要运行的操作的抽象。这些抽象表示数据存储并使用数据库实现的事实与实体或域模型的任何部分无关。这些抽象被称为DDD中的存储库。

回答你的问题:

  • 服务是如何初始化并注入到域实体中的?-当实体被从持久性中提取出来时,它是通过实现它所需要的抽象来初始化的,与实体的数据一起。
  • 那么单一的责任模式呢?-那它呢?实体只有一个责任:表示与单个域概念相关的行为。
  • 这不违背可重用性吗?-它实际上是高度可重用的。特别是如果您应用其他坚实的原则,并使用组合而不是继承。

对于您的示例来说,这可以通过具有接口引用的代理轻松解决,从而允许它以不同的方式查询卡片。然后,这些方法调用这个接口。

票数 2
EN

Software Engineering用户

发布于 2014-04-14 08:16:57

您说的是什么意思,但是代理只需要依赖3个DAO类来承担一项责任?如果您讨论的是避免域类中的DAO调用,也许您可以这样设计它:

代码语言:javascript
复制
class Agent {

   List<Card> assignedCards;

   int numberOfRemainingCards() {
      return assignedCards.size();
   }

   void sell(Card card) {
      // do something
      assignedCards.remove(card);
   }

   void damaged(Card card) {
      card.damaged = true;
      assignedCards.remove(card);
   }

}

class Card {

   String id;

   boolean damaged;

}

您只需要对DAO (或存储库)进行一次调用,就可以使用它们的Agent来检索assignedCards。它只涉及一个DAO,例如:

代码语言:javascript
复制
List<Agent> agents = AgentDAO.getAllAgents();
for (Agent agent: agents) {
   System.out.println("Remaining cards for " + agent.name + 
                      " is " + agent.numberOfRemainingCards());
}

另一个例子是:

代码语言:javascript
复制
Agent agentA = AgentDAO.findByName("Agent A");
agentA.sell(aCard);
agentA.damaged(anotherCard);
System.out.println("Number of remaining cards: " + agentA.numberOfRemainingCards());
AgentDAO.update(agentA); // if necessary

如果Agent有大量的Card,并且您不想仅仅为了确定剩余的Cards的数量而检索所有的Card,则可以将剩余卡片的数量存储为状态,例如:

代码语言:javascript
复制
class Agent {

   List<Card> assignedCards;

   int numberOfRemainingCards;

   int getNumberOfRemainingCards() {
      return this.numberOfRemainingCards;
   }

   void sell(Card card) {
      // do something
      assignedCards.remove(card);
      numberOfRemainingCards--;
   }

   void damaged(Card card) {
      card.damaged = true;
      assignedCards.remove(card);
      numberOfRemainingCards--;
   }

   void assign(Card card) {
      assignedCards.add(card);
      numberOfRemainingCards++;
   }

}
票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/235311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档