是否适合在模型中重复数据以满足集合中使用demeter的规律?

这是一个人为的例子,我想列出一个人有朋友的国家的人口,下面是两个设置。 是否最好在模型中重复数据?

我被告知德米特法则很重要,例如你告诉狗走路,指挥他的腿走路是愚蠢的。

在我丰富的经验(noob)中,我发现当模型重复数据时,查询会更容易, People.where(:country => friend.country) ,以及存在链接关联的集合(已经存在到目前为止不可能): People.where(:city => { :county => { :region => { :country => friend.city.county.region.country }}}) (这真的有助于这个noob在这里理解这个概念如果你能想象出正确设计的LoD设置和语法,我真的希望我没有使用与Demeter法则无关的例子)我试过通过delegate应用LoD并被告知我仍然链接(我是),我能想到的唯一解决方案是重复可以通过关联访问的数据。

但我讨厌重复数据! 这是由于我们重新创建了推特后DHH的Rails tutuorial,他展示了创建关系与重复数据的关系。

重复数据是否适合使关联更少链接?

模型,重复数据

 class Country < ActiveRecord::Base has_many :regions has_many :counties has_many :cities has_many :people end class Region < ActiveRecord::Base has_one :country has_many :counties has_many :cities has_many :people end class County < ActiveRecord::Base has_one :country has_one :region has_many :cities has_many :people end class City < ActiveRecord::Base has_one :country has_one :region has_one :county has_many :people end class Person  :relationships end 

vs具有链式关联的模型

 class Country < ActiveRecord::Base has_many :regions end class Region < ActiveRecord::Base belongs_to :country has_many :counties end class County < ActiveRecord::Base belongs_to :region has_many :cities end class City < ActiveRecord::Base belongs_to :county end class Person < ActiveRecord::Base belongs_to :city end 

这似乎不是demeter定律的问题,因为它是数据库设计和数据完整性的问题。 应该排除第一个选项,因为它创建的数据库肯定违反了第三范式(3NF):

在您的第一个示例中,如果是国家/地区HM城市,如果发生了什么,您更新该城市是否属于不再属于该国家/地区的其他区域? – > Bam! 数据完整性已经消失! 当然,一个城市不太可能迁移到另一个国家,但就像你说的那样,这是一个人为的例子,我在谈论一般情况

你应该谷歌数据库规范化和第三范式更多。

此外,在这种情况下,您违反3NF只是因为您认为可以通过这样做来“提高性能”。 这是预优化和不良实践的情况。 虽然在某些情况下,非规范化是一种管理风险,但这里有龙,如果你刚刚在rails中启动应用程序,那绝对不是这种情况。 让您的DB担心快速获取数据。 你可以通过提供良好的索引来帮助它。

另外,我认为你正在寻找的是一种创建嵌套的方法,它有许多通过关系。 你希望它是这样的:

通过地区的国家HM县

然后,

通过县的国家HM城市

这将是3.1中的标准,如果你在3.0,那么你可以使用

https://github.com/ianwhite/nested_has_many_through

gem,我目前正在使用,我很高兴。

啊, “德米特偶尔有用的建议” 。 (马丁福勒。)

我认为DIE / DRY和规范化是更基本的原则,但它最终将成为你需要应用常识的冲突指南之间的较量。

“法则”适用于一个特定项目中的对象类,并且作为类层次结构设计模型具有明显的价值。

但是Demeter的应用程序特别针对Rails视图存在争议。 根据定义,它们是一份报告,因此值得怀疑的是Demeter的建议是否适用。

在我看来,你应该尽可能避免数据的重复。 但是,您可以创建允许组合数据的聚合对象。 因此,您可以保持核心实体的清洁,但是可以使用其他支持实体来聚合对象。

如果使用SQL中的View示例,则可以检索结果,该结果是许多实体的组合。 这个结果可能是agreggate实体,是一种完全合法的“重复”数据方式。

Interesting Posts