代码之家  ›  专栏  ›  技术社区  ›  A O

如何分解一个大的init(由于大量的计算),以获得更好的可读性?

  •  1
  • A O  · 技术社区  · 6 年前

    我有一个班,有100个属性(夸张地说)。 这些属性中的大多数必须根据用户的偏好进行计算。

    let 属性

    用户可以设置几十个首选项,根据设置的首选项组合,当我初始化一个对象时,这里的属性将发生变化。

    let prop1:String
    let prop2:String
    ...
    let prop100:String
    
    init(maybeRelevantArg:Int, maybeRelevantArg2:String) {
        var proposedProp1 = ""
        //20 lines of logic to compute proposedProp1, referencing preferences and maybeRelevantArgs
        self.prop1 = proposedProp1
    
        var proposedProp2 = ""
        //20 lines of logic to compute proposedProp2, referencing preferences and maybeRelevantArgs
        self.prop2 = proposedProp2
    }
    

    你明白了,在这一点上,我的 init 会有几百行,基本上看不懂。

    我想把这些逻辑块分成不同的方法,比如:

    init(maybeRelevantArg:Int, maybeRelevantArg2:String) {
        self.computeAndSetProp1(relevantArg:maybeRelevantArg1)
        self.computeAndSetProp2(relevantArg:maybeRelevantArg2)
    }
    
    func computeAndSetProp1(relevantArg:String) {
        var proposedProp1 = ""
        //20 lines of logic to compute proposedProp1, referencing preferences and relevantArgs
        self.prop1 = proposedProp1
    }
    

    这条路 初始化 更易于阅读,并且应该更易于调试和维护。

    问题是编译器显然不会高兴我的 初始化 方法没有显式初始化这些属性,我得到类似于:

    “self”在初始化所有存储属性之前使用

    computeAndSetProp1() ,我将得到以下错误:

    无法分配给属性:“prop1”是“let”常量

    有没有办法把这个大的init分开?

    2 回复  |  直到 6 年前
        1
  •  1
  •   user1118321    6 年前

    你可以做 computeAndSetProp1()

    func computeAndSetProp1(relevantArg: String) -> String {
        var proposedProp1 = ""
        //20 lines of logic to compute proposedProp1, referencing preferences and relevantArgs
        return proposedProp1;
    }
    
    class someClass: NSObject {
        let prop1 : String
        let prop2 : String
        override init() {
            prop1 =  computeAndSetProp1(relevantArg: "x")
            //...etc.
        }
    }
    

    我还建议你看看能不能概括一下 computeAndSetProp* 减少代码量的函数。你可以把代码贴在 Code Review

        2
  •  0
  •   rounak    6 年前

    一种方法是将init参数存储在private let属性中,并将计算放在计算的var中。如果希望计算逻辑只发生一次,也可以将计算放在private(set)lazy var中。

    另一个想法是将类分解为多个具有相关属性的类/结构,然后让现有的类保留这些较小的类/结构。