我正在开发我的第一个 Core Data 项目(在 iPhone 上)并且我真的很喜欢它。核心数据是很酷的东西。
然而,我遇到了一个设计困难,我不确定如何解决,尽管我认为这是一个相当常见的情况。它涉及数据模型。
为了清楚起见,我将使用一个想象的足球比赛应用程序作为示例来说明我的问题。假设有 NSMO,称为 Downs 和 Plays。播放功能类似于唐斯使用的模板。用户创建 Play(例如 Bootleg、Button Hook、Slant Route、Sweep 等)并填写各种属性。戏剧与唐斯有一对多的关系。对于每个 Down,用户决定使用哪个 Play。当执行 Down 时,它使用 Play 作为其模板。每次运行后,都会将其存储在历史记录中。该程序会记住所有打过的唐斯比赛。
到目前为止,一切都很好。这一切工作正常。
我的问题涉及当用户想要更改 Play 的详细信息时会发生什么。假设它最初涉及向左传球,但用户现在希望它是向右传球。然而,进行这一更改不仅会影响该 Play 的所有未来执行,而且还更改历史记录中存储的 Play 的详细信息。实际上,唐斯的记录被“污染”了,因为播放模板已被更改。
我一直在研究针对这种情况的几种可能的解决方案,但我想 SO 的天才们比我更了解如何处理这个问题。尽管如此,我提出的潜在解决方案是:
戏剧的“版本控制”。对 Play 模板的每次更改实际上都会创建一个具有相同名称的新的、单独的 Play 对象(据用户所知)。然而,在幕后,它实际上是一个不同的游戏。这会起作用,AFAICT,但似乎它可能会导致 Play 对象的疯狂扩散,尤其是。如果用户不断在同一 Play 的多个版本之间来回切换(每次用户切换时都会创建一个又一个对象)。是的,该应用程序可以检查预先存在的相同的 Plays,但是......它看起来就像一团糟。
让唐斯在保存时记录他们使用的 Play 的详细信息,但不作为 Play 对象。这看起来很荒谬,因为 Play 对象是there只保留那些细节。
认识到 Play 对象实际上实现了 2 个功能:一是作为 Down 的模板,二是记录使用的模板。这两个函数与 Down 有不同的关系。第一个(模板)具有一对多关系。但第二个(记录)具有一对一的关系。这意味着创建第二个对象,例如“Play-Template”,它将保留与 Downs 的一对多关系。播放对象将被重新配置为具有一对一与唐斯的关系。 Down 将使用 Play-Template 对象来执行,但使用新类型的 Play 对象来存储所使用的模板。正是这种从一对多关系到一对一关系的转变才是问题的症结所在。
即使把这个问题写出来也帮助我变得更加清晰。我认为解决方案 3 之类的东西就是答案。然而,如果有人有更好的想法,或者只是确认我走在正确的轨道上,那将会很有帮助。 (请记住,我并不是真的在制作足球游戏,只是使用每个人都能理解的比喻更快/更容易。)
我认为你需要重新开始你的设计。
(1) 为什么使用PlayEntity作为DownEntity的模板?实体实际上是(在底层)类,因此类定义本身就是每个实例的“模板”。
(2) 被管理对象应代表真实对象或真实信息关系的数据模型。因此,您需要认真思考您想要建模的真实对象或信息是什么。一个好的起点是问问自己如何用笔和纸记录这些信息。
在你的例子中,上场和下场模拟了完全不同的东西。
Down 是按时间顺序发生的事件。在任何特定的游戏中,只有一个特定的“Down”。这意味着足球历史上每场比赛中的每场比赛都是独一无二的。因此,Down 数据模型实体主要感兴趣的是对Down 与其他Down 以及整个游戏的时间关系进行建模。
相比之下,戏剧是一个空间事件。比赛并不是唯一的,并且经常在一场比赛中以及在一场比赛之间重复出现。比赛实体应该关注球员、球和场地之间的空间关系。
你最终会得到这样的结果:
DownEntity{
game;
half;
quarter;
turnover;
gameClockTime;
yardLine;
penalties;
play --(required,Cascade)->PlayEntity.down
previousDown --(optional, nullify)-->Down.nextDown;
nextDown --(optional, nullify)-->Down.previousDown
}
PlayEntity {
playName;
//whatever other detail you want to model
down --(optional,nullify)-->>DownEnity.play;
}
请注意,两个实体都不会复制另一个实体的属性中保存的信息。它们也不共享继承,因为它们没有对游戏的相同方面进行建模。 Down 模拟时间序列,Play 模拟空间序列。这需要他们两个都完整地描述每一次下来所发生的事情。
您可以通过首先创建您想要的任何标准化 PlayEntities 来构建数据库。如果您有一部小说,您将创建一个新的 PlayEntity 并根据需要填充它。每次您有一个 Down 时,您都会创建一个 DownEntity 并创建与现有或新创建的 PlayEntity 的关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)