核心数据模型设计 - 改变“活动”对象还更改保存的对象 [英] Core Data Model Design - Changing "Live" Objects also Changes Saved Objects

查看:91
本文介绍了核心数据模型设计 - 改变“活动”对象还更改保存的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发我的第一个Core Data项目(在iPhone上),我真的很喜欢它。核心数据是很酷的东西。

I'm working on my first Core Data project (on iPhone) and am really liking it. Core Data is cool stuff.

然而,我遇到了设计难度,我不知道该如何解决,虽然我想这是一个相当普遍的情况。它涉及数据模型。

I am, however, running into a design difficulty that I'm not sure how to solve, although I imagine it's a fairly common situation. It concerns the data model.

为了清楚起见,我将使用一个假想的足球游戏应用程序作为例子来说明我的问题。说有NSMO的叫做Downs和Plays。播放功能与模板一样由Downs使用。用户创建播放(例如,Bootleg,Button Hook,Slant Route,Sweep等)并填充各种属性。戏剧与唐斯有一对多的关系。对于每个Down,用户决定使用哪个Play。当执行Down时,它使用Play作为其模板。每次运行后,它被存储在历史中。该程序记住了所有已经玩过的羽毛。

For the sake of clarity, I'll use an imaginary football game app as an example to illustrate my question. Say that there are NSMO's called Downs and Plays. Plays function like templates to be used by Downs. The user creates Plays (for example, Bootleg, Button Hook, Slant Route, Sweep, etc.) and fills in the various properties. Plays have a to-many relationship with Downs. For each Down, the user decides which Play to use. When the Down is executed, it uses the Play as its template. After each down is run, it is stored in history. The program remembers all the Downs ever played.

到目前为止,这么好。这一切工作正常。

So far, so good. This is all working fine.

我的问题是,当用户想要更改Play的详细信息时会发生什么。让我们说它最初涉及到左边的传球,但是用户现在想要它是一个传球到右边。但是,这种变化不仅会影响该Play的所有未来执行,而且还会更改存储在历史记录中的播放的详细信息。 Downs的记录被污染,实际上,因为Play模板已更改。

The question I have concerns what happens when the user wants to change the details of a Play. Let's say it originally involved a pass to the left, but the user now wants it to be a pass to the right. Making that change, however, not only affects all the future executions of that Play, but also changes the details of the Plays stored in history. The record of Downs gets "polluted," in effect, because the Play template has been changed.

我已经绕过几个可能的解决方案,但我想象的天才的SO知道更多关于如何处理这个比我做。仍然,我想出的潜在修复是:

I have been rolling around several possible fixes to this situation, but I imagine the geniuses of SO know much more about how to handle this than I do. Still, the potential fixes I've come up with are:


  1. 版本化的戏剧。对Play模板的每个更改实际上创建一个新的,单独的Play对象,具有相同的名称(只要用户能够知道)。在引擎盖下,然而,它实际上是一个不同的游戏。这将工作,AFAICT,但似乎它可能会导致Play对象的野生扩散,esp。如果用户持续在同一个Play的几个版本之间来回切换(在每次用户切换之后在对象之后创建对象)。是的,应用程序可以检查预先存在的,相同的戏剧,但...它只是看起来像一团糟。

  1. "Versioning" of Plays. Each change to a Play template actually creates a new, separate Play object with the same name (as far as the user can tell). Underneath the hood, however, it is actually a different Play. This would work, AFAICT, but seems like it could potentially lead to a wild proliferation of Play objects, esp. if the user keeps switching back and forth between several versions of the same Play (creating object after object each time the user switches). Yes, the app could check for pre-existing, identical Plays, but... it just seems like a mess.

在保存时,记录他们使用的Play的详细信息,但不是Play对象。

Have Downs, upon saving, record the details of the Play they used, but not as a Play object. This just seems ridiculous, given that the Play object is there to hold those just those details.

认识到Play对象实际上是实现2个功能:一个作为一个模板为一个Down,另一个记录使用什么模板。这两个函数与Down具有不同的关系。第一个(模板)具有一对多关系。但是第二个(记录)有一对一的关系。这意味着创建第二个对象,例如Play-Template,它将保留与Downs的多对多关系。播放对象将被重新配置为具有与Downs的一对一关系。 Down将使用Play-Template对象来执行,但使用新的Play对象来存储使用的模板。正是这种从一对多关系到一对一关系的变化,代表了问题的症结所在。

Recognize that Play objects are actually fulfilling 2 functions: one to be a template for a Down, and the other to record what template was used. These 2 functions have a different relationship with a Down. The first (template) has a to-many relationship. But the second (record) has a one-to-one relationship. This would mean creating a second object, something like "Play-Template" which would retain the to-many relationship with Downs. Play objects would get reconfigured to have a one-to-one relationship with Downs. A Down would use a Play-Template object for execution, but use the new kind of Play object to store what template was used. It is this change from a to-many relationship to a one-to-one relationship that represents the crux of the problem.

即使写这个问题也帮助我变得更清楚。我认为解决方案3的答案是答案。但是,如果任何人有一个更好的主意,或者只是一个确认,我在正确的轨道,这将是有益的。 (记住,我不是真正做足球比赛,它只是更快/更容易使用每个人都能理解的隐喻。)

Even writing this question out has helped me get clearer. I think something like solution 3 is the answer. However if anyone has a better idea or even just a confirmation that I'm on the right track, that would be helpful. (Remember, I'm not really making a football game, it's just faster/easier to use a metaphor everyone understands.)

推荐答案

我认为你需要从你的设计开始。

I think you need to start over with your design.

(1)为什么使用PlayEntity作为模板的DownEntity?实体是真正的(在引擎盖下)类,所以类定义本身是每个实例的模板。

(1) Why are using a PlayEntity as a template for the DownEntity? Entities are really (under the hood) classes so the class definition itself is the "template" for each instance.

(2)托管对象应表示真实对象或真实信息关系的数据模型。因此,你需要仔细思考你正在尝试建模的真实对象或信息。一个好的开始的地方是问自己如何用钢笔记录这些信息。

(2) Managed Objects should represent data models of real objects or real information relationships. Therefore you need to think hard about what you the real objects or information you are trying to model. A good place to start is to ask yourself how this information would be recorded with pen and paper.

在你的例子中,Plays和Downs模型完全不同的东西。

In your example, Plays and Downs model entirely different things.

A Down是按时订购的事件。在任何特定的游戏中只有一个特定的。这意味着每一个在足球历史上的每一场比赛中打出的每一个都是完全独特的。因此,Down数据模型实体将主要关注于将Down的关系在时间上与其他downs和总游戏建模。

A Down is an event ordered in time. There is only one particular Down in any particular game. This means every Down every played in every game in the history of football is utterly unique. A Down data model entity therefore would be primarily interested in modeling the Down's relation in time to other downs and the total game.

相反的戏剧是一个空间事件。戏剧不是唯一的,并且经常在游戏和游戏之间重复。 Play实体应该关心玩家,球和场之间的空间关系。

A Play by contrast is a spatial event. Plays are not unique and are often repeated within a game and from game to game. A Play entity should be concerned with the spatial relationships between players, the ball and the field.

你会得到这样的结果:

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模拟空间序列。它需要他们两个完全描述每一个发生了什么。

Note that neither entity duplicates information held in the attributes of the other. Neither do they share inheritance because they don't model the same aspects of the game. The Down models a temporal sequence and the Play models a spatial one. It requires both of them to completely describe what happened upon each down.

您将首先创建所需的任何标准化PlayEntities来构建数据库。如果你有一个小玩意,你会创建一个新的PlayEntity并根据需要填充它。每次你失败,你将创建一个DownEntity并创建一个与现有或新创建的PlayEntity的关系。

You would build your database by first creating any standardized PlayEntities you wanted. If you had a novel play, you would create a new PlayEntity and populate it as needed. Every time you had a down you would create a DownEntity and create a relationship to an existing or newly created PlayEntity.

这篇关于核心数据模型设计 - 改变“活动”对象还更改保存的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆