cover-image

About Refactor

很多项目在最开始的时候可能会希望快速迭代,这个时候由于考虑不到位、不周全,很多的项目在后面可能会面临无法继续维护,增加新特性的问题。

何时重构

发现问题的时候就是重构的最佳时机

嘴里总是会说,下个版本重构,下个版本重构,这就像是 明日复明日,明日何其多 ,不然真的到了无法维护的地步再去重构那将面临的巨大工作量,代价将会是巨大的

怎样重构

在重构的时候我们可能同时还有很多项目会并行进行,这个时候如何重构就要因情况而定了

  • 你的TeamLeader专门安排了重构项目(短期小规模)
  • 你需要大规模重构切时间跨度较大
  • 你需要在项目中完成重构并且时间有限

针对以上的不同情况我们有不同的重构方案,

在短期小规模并且专门进行重构的时候我们可以直接将需要旧代码重写掉,这个时候一定要注意,重构的前提是测试,你需要将测试用例完善后再开始写代码,千万不要前后颠倒

那么在时间有限的项目或事大规模的重构中我们应该如何做呢,这个时候就会有两种方式

  • 将所有重构放在新的版本控制分支上,全部更新完成后合并回主分支
  • 一边重构一边开发,同时进行在项目分支上

全部做完再合并回主分支会有一个缺点,当你完成全部工作合并回主干分支的时候可能会遇到海量的冲突,会很烦躁,如果你平时持续的合并也可能会遇到各种冲突,那么最佳解决办法其实就是第二种,开发的同时进行重构。

怎样能够在开发的同时重构呢,要知道,完成整个重构项目可能会经历多个项目才能完成,这里就可以用设计模式中的桥接模式进行处理

比如我们有以下用来记录日志的工具

struct CommonLog {
    func log(str: String) {
        print(str)
    }
}

在重构的时候则可以这样改

protocol logable {
    func log(str: String) -> Void
}

struct NewLog: logable {
    func log(str: String) {
        print("new:" + str)
    }
}

struct CommonLog {
    
    let newLog: logable?
    
    func log(str: String) {
        
        #if !DEBUG
        print(str)
        #endif
        
        #if DEBUG
        if let newLog = newLog {
            newLog.log(str:"asd")
        }
        #endif
    }
}


let log = CommonLog(newLog: NewLog())

log.log(str: "record1")

DEBUG 在这里只是举个例子,不过道理大同小异,在测试的时候app会执行我们新的逻辑,在发布到生产环境的代码中仍然使用重构前的代码来保障线上安全,可以通过build的config参数自定义打包规则,这样也方便测试发现问题。在重构完成后只要将桥接模式的宿主类全部替换掉就可以辣。

重构技巧

重构的小技巧,为了不让重构变得没有意义,自己总结了几点

  • 不要使用无意义的单例,能不用就不要用,因为全局对象很多时候真的是不必要的,反而常驻内存再加上持有了一些其他对象会浪费内存
  • 重视多线程,耗时的IO操作等请放非主线程,不重要的操作可以考虑使用background优先级的线程,不要什么东西都一股脑放进主线程做,
  • 回调的消耗其实对比下来使用代理要优于使用block
  • 配置要清晰,如果需要外部传递参数则越少越好,可以参考SDWebImage的接口
  • 整数类型的属性最好配置成枚举类型的,不仅方便扩展也更加利于阅读,swift中字符串也可以使用Switch
  • 组件化思想,在一开始就吸取经验,面向扩展开放,面向修改关闭
  • 方法名不要怕长,要足够能体现方法的内容
  • 重构之后一定注意要删除那些已经不再使用的代码