Swift Optionals最佳实践

Swift Optionals最佳实践,swift,class,Swift,Class,我想我理解Swift optionals背后的理念,即非可选类型的属性表示必须拥有,而可选类型的属性表示可能拥有,但在我看来,它似乎是这些功能之一,如强制异常处理或强制缩进,虽然理论上伟大,但也会产生一些意想不到的实际后果。这就是我面临的情况。我正在创建一个医学应用程序来评估认知能力。该测试由提供者对患者进行管理,它由10种不同的活动组成。应用程序的数据模型是一个简单的类Test,用于收集活动的结果。每个活动都有自己的类,患者和提供者也有自己的类。业务逻辑规则规定所有活动必须完成,否则测试无效,

我想我理解Swift optionals背后的理念,即非可选类型的属性表示必须拥有,而可选类型的属性表示可能拥有,但在我看来,它似乎是这些功能之一,如强制异常处理或强制缩进,虽然理论上伟大,但也会产生一些意想不到的实际后果。这就是我面临的情况。我正在创建一个医学应用程序来评估认知能力。该测试由提供者对患者进行管理,它由10种不同的活动组成。应用程序的数据模型是一个简单的类
Test
,用于收集活动的结果。每个活动都有自己的类,患者和提供者也有自己的类。业务逻辑规则规定所有活动必须完成,否则测试无效,患者和提供者显然是强制性的。类
测试的自然定义是

 class Test {
    var provider: Provider
    var patient: Patient
    var activity1: Activity1
    var activity2: Activity2
    ...
    var activity10: Activity10
    }
现在的问题是,要创建class
Test
的实例,我需要所有活动的所有结果;在实践中,我必须执行
提供者
患者
的所有单独实例和活动,并且仅在测试完成时创建
测试
的实例,这当然是不切实际的。因此,出于实际目的,
Test
的所有属性都可以是可选的,并且类以增量方式填充,但是现在类
Test
不能忠实地表示数据模型;此外,必须打开对属性的任何访问。一种选择是创建一个非可选的活动数组,该数组可以增量增长,但该类再次不能表示数据模型的意图。最后,可以创建一个带有所有可选属性的“姐妹类”
PartialTest
,当
PartialTest
完全填充时,创建一个
Test
的实例。不过,这似乎有点过头了


那么,我是否误解了期权在Swift中的作用?如果没有,是否有切实可行的方法使类
测试保持原样?

您可以执行以下操作:

class Test {
    var provider: Provider
    var patient: Patient
    var activity1: Activity1! = nil
    var activity2: Activity2! = nil
    // ...
    var activity10: Activity10! = nil

    var isComplete: Bool {
        return activity1 != nil
            && activity2 != nil
            // ...
            && activity10 != nil
    }
}
。。。然后,只有当测试中的活动具有
isComplete==true
时,才可以访问它,我认为可以从概念上改进设计

但一般来说,我会重新考虑设计,避免在测试课上用一套硬编码的活动来限制自己。例如:

protocol Activity {
    var isMandatory: Bool { get }
    var isComplete: Bool { get }
}

struct Activity1: Activity {
    let isMandatory: Bool

    var result1: Int! = nil

    var isComplete: Bool {
        return result1 != nil
    }

    init(isMandatory: Bool) {
        self.isMandatory = isMandatory
    }
}

class Test {
    var provider: Provider
    var patient: Patient
    var activities: [Activity] = [
        Activity1(isMandatory: true)
        // ...
    ]

    var isComplete: Bool {
        return activities.reduce(true) {
            $0 && $1.isComplete
        }
    }
}
。。。或者某种更好的方法