减少多个if else语句的循环复杂性

时间:2017-07-31 11:37:54

标签: ios swift cyclomatic-complexity

我有一个函数接受Textfield作为参数,并根据标记,数字改变;这是代码示例

func textFieldDidChange(_ textField: UITextField) {
    if(textField.tag == 0){
        measureMentObject?.bloodPressureSystolic = myNumber
    }else  if(textField.tag == 1){
        measureMentObject?.bloodPressureDiastolic = myNumber
    }else  if(textField.tag == 2){
        measureMentObject?.heartRate = myNumber
    }else  if(textField.tag == 3){
        measureMentObject?.bodyTemperature = myNumber
    }else  if(textField.tag == 4){
        measureMentObject?.respitoryRate = myNumber
    }else  if(textField.tag == 5){
        measureMentObject?.o2Saturation = myNumber
    }else  if(textField.tag == 6){
        measureMentObject?.painScale = myNumber
    }else  if(textField.tag == 7){
        measureMentObject?.weight = myNumber
    }else  if(textField.tag == 8){
        measureMentObject?.po = myNumber
    }else  if(textField.tag == 13){
        measureMentObject?.gastricTube = myNumber
    }
}

在这种情况下,如何降低cyclometic复杂度?

4 个答案:

答案 0 :(得分:1)

如果确实希望摆脱if / else if阻止,那么一种方法是:

  • 子类UITextField
  • 给它一个measureMentObjectKey: String属性

然后:

func textFieldDidChange(_ textField: UITextField) {
    if let tf = textField as? MyTextField {
        let tfKey = tf.measureMentObjectKey
        measureMentObject.setValue(myNumber, forKey: tfKey)
    }
}

(当然还有额外的错误检查)。

答案 1 :(得分:1)

一种方法是使用一些setter闭包创建Array

class Measurement {
  var bloodPressureSystolic : Float = 0.0
  var bloodPressureDiastolic: Float = 0.0
  var heartRate             : Float = 0.0
  // ...

  // Array of property setters
  lazy var setters:[(Float) -> ()] = [
    { [unowned self] in self.bloodPressureSystolic  = $0 },
    { [unowned self] in self.bloodPressureDiastolic = $0 },
    { [unowned self] in self.heartRate              = $0 }
  ]
}

使用示例:

var bar = Measurement()

print(bar.bloodPressureSystolic)
// "0.0"

bar.setters[0](5.0)

print(bar.bloodPressureSystolic)
// "5.0"

请注意,这只会将switch..caseif..else语句的复杂性移至选择Array成员。它可能会或可能不会更复杂,但如果以某种方式实现Array,它可以使用计算的偏移来查找成员。

为方便起见,我可能会添加enum

  // Convenience enum for property setter array
  enum PropertyValues: Int {
    case bloodPressureSystolic
    case bloodPressureDiastolic
    case heartRate
    // ...
  }

您可以像以下一样使用它:

bar.setters[Measurement.PropertyValues.bloodPressureSystolic.rawValue](5.0)

另一种方法是继承NSObject并使用KVC

class Measurement:NSObject {
  var bloodPressureSystolic: Float = 0.0
}

bar.setValue(10.0, forKey: "bloodPressureSystolic")
// Example only, avoid forced unwrapped Optionals!!!
print(bar.value(forKey: "bloodPressureSystolic") as! Float)

然后,您可以使用相同的Array技巧,但使用String值将索引转换为关键字符串。

答案 2 :(得分:0)

您应该创建枚举以创建更具可读性的

  enum SelectedTagTextField {
    case bloodPressureSystolic = 0
    case bloodPressureDiastolic = 1
    ...
  }

并使用

 switch(SelectedTagTextField(rawValue: textField.tag)) {
    case  SelectedTagTextField.bloodPressureSystolic : 
  .... And So on 
}

希望有所帮助

答案 3 :(得分:0)

简单地说,不要使用一个处理程序。使用多个:

@IBAction
func systolicBloodPressureTextFieldChanged(_ textField: UITextField) {
    measureMentObject?.bloodPressureSystolic = myNumber
}

@IBAction
func diastolicBloodPressureTextFieldChanged(_ textField: UITextField) {
    measureMentObject?.bloodPressureDiastolic = myNumber
}

并将其与.editingChanged操作相关联。

这也可以让你避免那些邪恶的标签。