【问题标题】:Swift Optionals best practicesSwift Optionals 最佳实践
【发布时间】:2015-07-03 17:13:02
【问题描述】:

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

 class Test {
    var provider: Provider
    var patient: Patient
    var activity1: Activity1
    var activity2: Activity2
    ...
    var activity10: Activity10
    }

现在的问题是,要创建类Test 的实例,我需要拥有所有活动的所有结果;在实践中,我必须继承ProviderPatient 和活动的所有单个实例,并且只有在测试完成时才创建Test 的实例,这当然是不切实际的。因此,出于实际目的,Test 的所有属性都可以设为可选,并且类会逐渐填充,但现在Test 类并不能忠实地表示数据模型;此外,必须解开对属性的任何访问。一种选择是创建一个非可选的活动数组,这些活动可以增量增长,但该类再次不能代表数据模型的意图。最后,可以创建一个具有所有可选属性的“姐妹类”PartialTest,当PartialTest 完全填充时,创建Test 的一个实例。仍然看起来有点过头了。

那么,我是否误解了 Swift 中可选项的作用?如果没有,是否有任何实用的方法来保持课程Test 应有的状态?

【问题讨论】:

    标签: swift class


    【解决方案1】:

    你可以这样做:

    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时才访问活动,我认为设计可以在概念上进行改进。

    但通常我会重新考虑设计,以摆脱在 Test 类中使用一组硬编码的活动来约束自己。例如:

    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
            }
        }
    }
    

    ...或者某种更好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-20
      • 2018-09-12
      相关资源
      最近更新 更多