我对类的建模和底层数据库设计有疑问。
简单地说,情况如下:目前我们有Positions和Accounts对象和表,它们之间的关系是一个Position“有一个”账户(一个账户可以有多个头寸)。这是简单的聚合,在数据库中由持有账户 ID 作为外键的位置表处理。
我们现在需要通过交易 和投资组合 来“向下”扩展。一笔或多笔交易构成一个头寸(但一笔交易本身不是头寸),一个或多个投资组合构成一个账户(但投资组合本身不是账户)。交易与投资组合相关联,就像头寸与账户相关联一样(“有一个”)。请注意,仍然可以有一个没有交易的头寸和一个没有投资组合的账户(即,不必将所有现有对象分解为子组件)。
我的第一个想法是简单地进行以下操作(前两个类已经存在):
class Account;
class Position {
Account account;
}
class Portfolio {
Account account;
}
class Trade {
Position position;
Portfolio portfolio;
}
我认为(潜在的)问题很明确:从交易开始,您最终可能会进入不同的账户,具体取决于您选择的是头寸路线还是投资组合路线。当然,这绝不应该发生,创建和存储对象的代码永远不会造成这种不一致。我想知道理论上可能存在不一致的数据库这一事实是否意味着设计有缺陷?
期待您的反馈。
最佳答案
这个设计并没有缺陷,因为有两种方法可以从 A 类到 D 类,一种是通过 B 的方式,另一种是超过 C。这种“方 block ”经常出现在 OOP 类模型中,有时并不那么明显,尤其是当路径中有更多类时。但正如 Dan 所提到的,业务语义总是决定这样的正方形是否必须通勤(在数学意义上)。
我个人在 UML 图中的这样一个正方形内画了一个 =
符号,表示它必须通勤。我还注意到 UML 注释中的精确公式,在我的示例中它将是
For every object
a
of classA
:a.B.D = a.C.D
如果这样的谓词成立,那么您基本上有两个选择:
- 相信所有程序员都不会在任何代码中违反规则,因为它有很好的文档记录
- 实现一些错误处理(如提到的 Dan 和 algirdas),或者,如果您不想在模型中使用此类代码,请创建一个 Checker Controller ,它会检查给定模型实例中的所有条件。
关于oop - 理论上可以不一致的多个聚合是否可以接受?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12874552/