2009-10-30 136 views
1

我正在研究RoR应用程序,但这是OOP策略的一般问题。考虑一下存储多种类型的引用的情况:书籍,文章,演示文稿,书籍章节等。每种类型的引用都是层次结构的一部分,其中常见行为位于最一般的继承点上,在数据库级别,我使用单表继承。该类型是通过使用select选项设置的,因此可以说我输入的数据就好像它是一本书,但是后来才意识到它只是一个章节。因此,我通过选择“Book Chapter”来更改参考类型,然后将更新发布到现有模型/表单。问题是处理这个问题的正确策略是什么?将对象转换为其他类型

一方面,似乎最好转换数据库中的现有记录以避免id耗尽,并可能节省创建/删除记录的操作。然而,这往往会使更新策略变得复杂。

另一方面,使用旧对象创建一个新对象(和记录)来初始化想要保留的值,然后删除旧对象,似乎更符合一般对象方向。我认为这在对象空间(堆)方面更有意义,我认为它更像一般系统的思想。

但是,我还没有确定这一点,在坐了一会儿之后,我正在向这个社区投放它,看看有什么“正确”的方式来做到这一点。

回答

1

优选不可变对象,换句话说:第二种策略。你的对象本身可能不是一成不变的,但减少可变性往往是朝着正确方向迈出的一步。

除此之外,这是更自然的方式。在一般的OOP术语中,没有办法改变对象的类型。在你的情况下你可以,但它仍然是一个尴尬和不寻常的事情。另一方面,如果你的对象由相同的(相同的)类表示,并且通过设置高级属性来改变类型,那么可以说重新创建对象是矫枉过正的。

尽管如此,减少可变性是一个很好的想法,但是如果你的类已经被设计为可变的,那么它可能不值得。 (从语言的角度来看实际上只有一个实际班级的那种特殊情况)

1

您所谈论的转换似乎不能保证新纪录或新对象。

您引用的每个条目都具有相同的格式。他们是与兄弟姐妹,父母和孩子的文本块。例如,一章可能有一段文字,带有父书和孩子尾注。它们仅在数据库级别上与其类型区分开来,这本身可能是一个字段。

所有你需要的是一个模型来处理这些'元素'的不同取决于它是否被标记为书或章节等。如果元素被标记为章节,但没有父项,例如,您可以在将它保存到数据库时将其标记为“书”。

更改元素标记的方式不会更改元素,它只会改变查看方式。只要元素知道如何找到它的子元素,数据将以相同的方式进行计算。就模型而言,它只是一个你担心的因素。剩下的就是在UI中完成的。

+1

我同意。如果你的模型足够相似以保证单表继承,那么这些选项中的任何一个都可能比实际需要的工作方式更多。 – 2009-10-30 18:07:53

+0

也许我应该使用第二个例子。这不仅涉及数据的存储,还涉及数据的行为方式。另一个例子是我们为游戏创建脚本的位置,记录表示表达式节点。因此,让我们说我们有一个Effect类,并且有一些类似于Give和Take的效果,但是GiveMoneyEffects与GiveItemEffects有不同的要求,它们也需要选择项目。在这种情况下,存在表单行为更改以及处理时间问题。 什么是“正确”的事情呢? – adamaig 2009-10-30 19:02:13

+0

@adamaig那么,正确的做法可能是创建一个不同的子类的新对象。或者,您可以拥有模型检查的行为字段。如果您使用Ruby,您可能更愿意使用元编程为运行时的对象赋予它自己的功能。正如@NSD所评论的,正确的做法取决于你的模型的二态性以及你选择使用的语言/范式。 – deau 2009-10-30 19:42:52

相关问题