知道何时建模域关系以及如何处理上下文关系

时间:2009-06-06 14:40:33

标签: oop model dns entity-relationship

我是领域建模的新手,请原谅我提出几个基本问​​题。我的第一个问题是知道何时建立域关系模型。我发现有时候我觉得所有类似乎都与大多数其他类似,并且我不清楚何时应该直接建模这些关系(通过将一个类中的引用保存到另一个类中)。

例如,假设我有一个与订单集合相关的Person类,并且每个订单都与产品集合相关(原谅缺乏想象力的示例)。每个这些实体在数据库中都有一个对应的表。如果我正在编写一些处理Person关联的产品的客户端逻辑(通过那些人的订单),那么看起来很容易拥有一个Person.Products集合,特别是因为我可以制作一些SQL来获得这个集合而不需要拉回人员订单集合。这是好还是坏的设计?如果有更好的方法来解决这个问题呢?

其次,关系本质上是情境的情况又如何呢?继续前面的示例,我想要在person方法中运行的某些业务逻辑需要处理包含特定产品的所有Person的相关订单(即Person's Orders集合的子集)。我可以构造一些SQL,它将非常容易地返回这个子集。问题是我在哪里公开结果?我应该在Person上放一个方法来获取Product参数并返回Orders集合,以便客户端代码看起来像这样吗?

person.OrdersContaining(Product p)

实体是否有多个这样的方法来公开它们的关系的不同子集,或者一个Person只有一个Orders集合,而子集是以其他方式处理的?

由于

3 个答案:

答案 0 :(得分:2)

我在这里讨论两个问题:

People --- Order

People --- Order --- Product

1)。我们是否应该公开People.getOrders()和Order.getOrdersForPerson(p)?

2)。我们应该公开People.getProductsOrdered()吗?

本能地,在做了多年的事情之后,我会对这两个问题说“不”。但我可以证明这一点吗?什么启发式指导我们?一些建议:

A)。越少越好。每种方法都要花费开发时间,测试工作量,文档。找到你想要的方法越多,找到你想要的方法就越多。

B)。单一责任。如果我们接受暴露People.getOrders()和Order.getOrdersForPerson(p)os overkill,那么哪个对象真正负责People-Order关系。我会说订单的性质与订货人联系,因此订单应该拥有这种关系。

C)。脱钩。忙碌的人订购很多东西。您可能最终会有一个quialified getOrders()方法,采用其他条件,例如订购时或订单大小。公开您使用订单的属性。所以People.getOrders(标准)现在用订单内容的细节表示。如果您更改订单,则需要更改人员。耦合很糟糕!这一点解决了产品问题。很明显,Orders本质上需要了解产品并且与它们具有一定程度的耦合。人们没有这种内在关系,因此不要将它们与产品结合起来。

d)。规模。人们做很多事情。他们不只是下订单。您是否希望为他们所做的每件新事物更改People类?添加People.getTrips()People.getExpenseReimbursements(),People.getHeathCareClaims()。当然没有。

不要因为“在SQL中很容易实现”的论点,在这个级别的讨论中,我们更关心的是设计好的接口并清楚地分离可靠性。

答案 1 :(得分:1)

所有关系都是内容相关的。

如果用户请求您提供某人购买的产品列表,则他们定义一个人与产品相关联的上下文。没有上下文,就没有关系。

有一种常见的误解,即应用程序有一个域模型。这不可能是事实。原则上,每个功能都有不同的域模型。

您应该将每个功能都视为系统支持的 only 功能。将现有代码视为重用机会;不多也不少。并通过无情的重构来解决问题。

答案 2 :(得分:0)

  

如果我正在编写一些客户端逻辑   处理一个人的产品   与...相关联   人们命令)似乎很有诱惑力   有一个Person.Products集合,   特别是因为我可以制作一些SQL   得到这个集合没有   需要撤回人员订单   采集。这是好还是坏的设计?   如果什么是更好的方式   处理这个?

您在软件中编码的每个一流的关系都会对您的设计意图以及您对实体如何组合的理解做出陈述。不可思议地将People和Products链接起来可能被认为不是最优的,因为每次获得Person时,您也会得到他们的产品。这意味着人与产品之间可能实际上并不存在的关系。

  

实体是否有多个这样的方法来公开它们的关系的不同子集,或者一个Person只有一个Orders集合,而子集是以其他方式处理的?

我可能更喜欢可以处理这种事情的OrderService而不是将它放在实体上 - 它会有像List<Order> OrdersForPerson(Person p)这样的方法,等等。在某些框架中,将它放在实体上更为惯用,但在这里会想到Rails的ActiveRecord