为了简单起见:假设您有一个实体关系图(ERD),其中包含以下表格:
Survey
:ID、姓名、问题Question
:ID、文本、调查
在这种情况下,Survey
有一个或多个Questions
,而Question
只有属于一个Survey
。
我的问题是,我可以只使用类而不使用任何持久化层(如Realm或Core数据)来重新创建这个架构吗?这是我的意思的一个简单演示:
struct Survey {
var id: Int
var name: String
var questions: [Question] // 1 or more questions
}
struct Question {
var id: Int
var text: String
var survey: Survey // belongs to only one survey
}
字符串
我尝试了这种方法,但显然下面的代码不会工作,由于一对多的关系:
let survey = Survey(id: 0, name: "First survey", questions: [
Question(id: survey.id, text: "Whats your name", survey: survey) // This is not possible.
])
型
更多背景:我想创建一个调查应用程序。该应用程序的架构很难设计,因为调查将支持多种类型的问题(多项选择,开放性问题,是/否问题等).做一个在线搜索我发现有一些ERD设计的调查一样this之一.问题是,这个ERD设计是为数据库..但我不想创建一个数据库目前为止。我假设在架构上设计可以用类来表示。那么问题是如何表示?
2条答案
按热度按时间inb24sb21#
这两个对象之间存在依赖关系,因为两个结构体的初始化器都期望其他结构体在之前被创建,这只是设计上的错误。你可以通过使用optional或隐式展开optional(这是不安全的)来解决这种依赖关系。
这里有一个显而易见的解决方法,
字符串
所以,你可以创建一个对象而不需要创建其他结构,只需使用赋值就可以了,而不是在初始化器中传递对象。
型
izkcnapc2#
架构建模
ERD植根于关系代数,它主要用于关系数据库建模。然而,您可以完美地使用它来建模不使用关系数据库的架构,甚至没有任何持久性。
但ERD是在OOP相当陌生的时候发明的,存在几个扩展ERD变体(EERD),每个变体都试图以自己的方式解决继承和专门化问题,但语义较弱,没有权威标准。
修改架构
一个更好的方法是用UML类图建模你的设计,完全支持OOP和wiki可能看起来像:
的数据
事实上,支持“* 多种类型的问题 *”的意图强烈建议使用
Question
的某些专门化(子类型),因为多项选择的内容和行为与开放式问题非常不同。继承将允许应用Open Closed Principle,即轻松添加新类型的问题,而无需更改其余代码。对代码的影响:
Question
不能是struct
but aclass
或协议。问题是否需要知道其调查?
另一点是澄清为什么
Question
需要了解Survey
。我不确定,因此我使用了单向导航箭头。事实上,人们可以很容易地想象同一个问题在几个调查中使用。如果你需要它,你的设计是有问题的,因为很难像你的代码那样用问题初始化一个调查,而且,没有什么能防止不一致,一个问题引用的是另一个调查,而不是它所包含的调查。
为了解决这个问题,可以考虑不使用引用的设计,或者至少创建调查并通过两个步骤添加问题:一个方法而不是直接修改数组可以强制一致性。