Design patterns 数据库实体及其依赖项wrt local info。正确的设计?

Design patterns 数据库实体及其依赖项wrt local info。正确的设计?,design-patterns,Design Patterns,很抱歉这个古怪的标题,我需要一个仔细的解释来澄清我的意思 假设我有一个数据库作为一个普通的集合,它的作用是保存一组对象并按需返回它们。例如,我有一个包含Foo类型对象的Foo数据库。这些Foo对象是在FooDatabase的协调下从文件加载的 现在,附加信息必须存储在Foo对象中。此附加信息在文件中不可用,但与每个Foo相关。从技术上讲,如果这些信息是在每个Foo的责任范围内自我详细描述的,那么就不会有真正的问题:每个Foo计算这些信息,并将其存储在自身中 不幸的是,我的情况更复杂:这些信息不仅

很抱歉这个古怪的标题,我需要一个仔细的解释来澄清我的意思

假设我有一个数据库作为一个普通的集合,它的作用是保存一组对象并按需返回它们。例如,我有一个包含Foo类型对象的Foo数据库。这些Foo对象是在FooDatabase的协调下从文件加载的

现在,附加信息必须存储在Foo对象中。此附加信息在文件中不可用,但与每个Foo相关。从技术上讲,如果这些信息是在每个Foo的责任范围内自我详细描述的,那么就不会有真正的问题:每个Foo计算这些信息,并将其存储在自身中

不幸的是,我的情况更复杂:这些信息不仅依赖于主题上的Foo,还依赖于数据库中存储的其他一些Foo对象。我有两种可能来解决这个问题:

我将数据库本身传递给Foo对象,以便Foo可以查询数据库以查找计算信息所需的其他Foo对象 我将计算这些信息的责任委托给数据库对象,它是唯一能够看到整个画面的对象。一旦为每个Foo计算了信息,数据库就会将其推送到每个Foo中。Foo对象保存虚拟信息,直到发生这种情况。
您是否已经遇到了这个问题?对于这种情况,约定的设计是什么?

您所称的数据库(我认为类似于)将为操作提供一个接口,以便从底层数据存储中查询给定的Foo。Foo对象只是保存数据并提供检索数据的方法。根据我的经验,有两个选项可以根据需要相关Foo对象的频率应用

选项1:建筑商

如果您大部分时间都需要它们,您可以使用来处理这种情况。您有一个FooBuilder,它使用数据库提供的操作查询数据库并填充Foo对象上所需的数据。每当您需要一个特定的Foo时,您都会调用构建器,它会生成一个完全填充的Foo供您使用

选项2:延迟加载

如果您不经常需要相关的Foo数据,那么可以实现延迟加载解决方案。这可以使用。为了实现这一点,在FooBuilder上有一个buildUnfledFoo方法,该方法只加载初始Foo并提供UnfledState。UnfilledState实现需要额外数据的方法,方法是首先通过获取所需的其他Foo,将自身替换为FilledState,然后调用FilledState来执行操作

以下是我对您提出的其他选项的看法:

将数据库本身传递给Foo对象

正如您在评论中指出的,您正在向应用程序中引入循环依赖项。 使数据对象依赖于数据库实现,这将使将来更改数据实现变得更加困难。 将计算此信息的责任委托给数据库

这使得数据库成为与数据对象构造相关联的业务逻辑的所有者,而实际上它应该只处理数据查询
您所称的数据库(我认为类似于)将为操作提供一个接口,以便从底层数据存储中查询给定的Foo。Foo对象只是保存数据并提供检索数据的方法。根据我的经验,有两个选项可以根据需要相关Foo对象的频率应用

选项1:建筑商

如果您大部分时间都需要它们,您可以使用来处理这种情况。您有一个FooBuilder,它使用数据库提供的操作查询数据库并填充Foo对象上所需的数据。每当您需要一个特定的Foo时,您都会调用构建器,它会生成一个完全填充的Foo供您使用

选项2:延迟加载

如果您不经常需要相关的Foo数据,那么可以实现延迟加载解决方案。这可以使用。为了实现这一点,在FooBuilder上有一个buildUnfledFoo方法,该方法只加载初始Foo并提供UnfledState。UnfilledState实现需要额外数据的方法,方法是首先通过获取所需的其他Foo,将自身替换为FilledState,然后调用FilledState来执行操作

以下是我对您提出的其他选项的看法:

将数据库本身传递给Foo对象

正如您在评论中指出的,您正在向应用程序中引入循环依赖项。 使数据对象依赖于数据库实现,这将使将来更改数据实现变得更加困难。 委派责任 计算此信息到数据库的时间间隔

这使得数据库成为与数据对象构造相关联的业务逻辑的所有者,而实际上它应该只处理数据查询
如何记录其他Foo对象所需信息的外观?返回Foo对象A以及相关Foo对象列表,允许新生的Foo对象A查询数据库中缺少的信息如何?@p.marino:我有Fooone和Footwo,但我也有Fooone,two,这取决于前两个,以便计算其他信息。您是否可以向数据库添加一些行为,以便它可以为foo[1]和foo[2]返回每个节点的依赖项列表,并为foo[1,2]返回列表[1,2]?并允许foo[1,2]根据列表本身查询数据库中的任何其他信息?@p.marino:这个解决方案有两个问题。首先,我不太喜欢在数据库中包含一个对象来查询数据库本身,因为在构建数据库时,查询可能会发生。我倾向于远离循环依赖。第二个问题是所有东西都是用fortran编写的,所以我在实现上没有太多的灵活性,尽管这是一个设计问题,因此与语言无关。那么DB真的是一个通用的、无格式的数据存储?也就是说,它可以是一个文件、一个地图、一个JavaSpaces实例。。。这个问题不应该认为它在任何时候都是内在一致的吗?从某种意义上说,它可以从不同的线程/进程更新?这难道不可能确保您拥有构建任何FOO所需的所有信息吗?如果是这种情况,那么将DB push信息发送到Foos可能会更好。基本上,每个FOO都是自己的监听器,DB是更新事件的发布者。如何记录其他FOO对象所需的信息?返回Foo对象A以及相关Foo对象列表,允许新生的Foo对象A查询数据库中缺少的信息如何?@p.marino:我有Fooone和Footwo,但我也有Fooone,two,这取决于前两个,以便计算其他信息。您是否可以向数据库添加一些行为,以便它可以为foo[1]和foo[2]返回每个节点的依赖项列表,并为foo[1,2]返回列表[1,2]?并允许foo[1,2]根据列表本身查询数据库中的任何其他信息?@p.marino:这个解决方案有两个问题。首先,我不太喜欢在数据库中包含一个对象来查询数据库本身,因为在构建数据库时,查询可能会发生。我倾向于远离循环依赖。第二个问题是所有东西都是用fortran编写的,所以我在实现上没有太多的灵活性,尽管这是一个设计问题,因此与语言无关。那么DB真的是一个通用的、无格式的数据存储?也就是说,它可以是一个文件、一个地图、一个JavaSpaces实例。。。这个问题不应该认为它在任何时候都是内在一致的吗?从某种意义上说,它可以从不同的线程/进程更新?这难道不可能确保您拥有构建任何FOO所需的所有信息吗?如果是这种情况,那么将DB push信息发送到Foos可能会更好。基本上,每个FOO都是自己的监听器,DB是更新事件的发布者。