美文网首页
如何快速阅读老项目,并且完成维护和少量迭代任务

如何快速阅读老项目,并且完成维护和少量迭代任务

作者: 狼性刀锋 | 来源:发表于2018-10-18 17:48 被阅读58次

    如何快速阅读老项目,并且完成维护和少量迭代任务

    前言

    本人有幸参与一个生命周期以长达10年老项目的维护,并完成部分业务逻辑的重构,在这个过程中大大提高了自身阅读代码的能力。先说说所面对的问题

    1. 年代久远,中间经过了无数的人手,很多问题无法追溯
    2. 架构老化各种MRC,古老的API,以及非人类的架构设计
    3. 臃肿的代码,没有人能够真正的理解整个项目的运行机制,核心基类已达10000多行代码
    4. 没有文档,技术文档,测试文档什么的都没有,大部分已经失效了,有相当于没有

    先整体后局部

    其实当我拿到这份源代码的时候,内心是崩溃的,一种无从下手的感觉。没办法还是要硬着头皮干, 首先从APPDelegate 开始, 你们见识过一个AppDelegate超过1000行吗, didFinishLaunchingWithOptions 加载了十几个Services, 面对这种情况,就要多从整体上入手,先忽视具体细节,不要一行一行的阅读代码啦,从命名以及某些特征代码,判断具体某个Service是干什么的的。 经过上述操作大概得到类似的清单:

    • PushNotificationUtility: 推送消息工具(存储deviceToken, 配置远程推送信息,感觉不应该放在这个类里面,DataServices 没有对该类进行任何维护管理的操作)

    • WebtrendsService: 用户数据统计相关的

    • AppDynamics: 监控用户行为的工具类

    • AutoLogoffService: 日志开关

    • DataCacheUtility:存储一些全局参数,谁都可以存,谁都可以取,关键子没有详细的配置文件非常混乱

    • SoftTokenService: softTokenService:待了解 不知道干啥用的

    .........

    对各种Service 形成初步印象,做什么用,可能存在什么问题, 对于那些作用存疑先暂时打上标记

    找到关键入口

    不管didFinishLaunchingWithOptions怎么复杂,最终还是要进入ViewController的,这个时候需要弄明白什么时候会进入正常页面流程,什么时候进入异常页面流程。这里有一个拐点

    • 什么时候所有Services 加载完成,完成APP环境检测

    一旦完成APP环境检测,通常就会加载UI了,找出关键代码,并总结形成流程图


    UI入口.png

    快速定位页面

    如果你需要了解一个具体的页面,甚至修改,如何从茫茫文件中,快速定位到该页面?
    借助Xcode自带工具Debug View hierarchy, 定位到该页面并且对整个UI层级有个初步了解。
    [图片上传失败...(image-7668de-1539856111956)]


    Debug View hierarchy.png

    多做记录

    有的时候你可能当时理解该流程,过段时间可能就忘了,或者变得不清晰了。这个时候保持良好的书写文档方式,能够避免重复的劳动。

    • 摘抄部分关键入口代码
    • 对于逻辑复杂的地方,截取关键的堆栈信息
    • 保存必要的网路日志
    • 建立UML 类图时序图流程图等,整体上理解APP结构
    UI类图 预登录堆栈信息.png

    如何修改

    1. 非必要不引入第三方库,本来就是一台拖拉机了,你还在上面加东西,就不怕他散架吗,尽量使用原生API开发功能,可以基于项目需要自己开发一些工具类,够用就好不需要像开源框架那么强大和全面的功能
    2. 慎重优化代码,因为你一旦改动可能会引发新的Bug,而测试人员根本就发现不了,因为他根本没法侧。有些代码里面可能看似没有用,却有可能是其他模块正常工作的必要条件。所以不要想当然去优化一些代码,除非你已经彻底搞清楚了该段代码的逻辑
    3. 对于修改的代码添加必须追加注释, 谁改的,什么时候改的,为什么要改,修改的代码从哪个位置开始到哪个位置结束,原来的代码逻辑是什么,这么做的原因在于使问题变得可追溯,一旦遇到问题可以快速定位是历史遗留问题,还是新代码所带来的问题。
      类似这样:
       //Bug Fix #1494.EULA issue Start: by Emmy Xiao on 10/08/2014
      //Description: French EULA should not be displayed if customer has accepted an English EULA previously
      [[ControllerManager getDataServices].regionDataSource checkUpdateEulaAcceptLanguage];
      //Bug Fix #1494.EULA issue End: by Emmy Xiao on 10/08/2014
    
    

    主题,描述,code

    1. 对文件夹的管理, 通常情况我们都是按照功能模块,管理不同的文件。但是对于老项目的话,我们可以建立一个新的文件夹,用于存放新增的文件,达到新老文件分离的目标。 新增的文件可以考虑加个特殊标识符。

    形成文档

    • 对于你要修改的部分,在理解完毕之后, 完成文档整理
    • 对新功能的设计,也要形成文档。

    这样做的话,首先对原逻辑整理文档有利于加速你的理解, 同时也为自己的设计提供参考,更便于以后的维护。

    networkQueue.png

    这是一个原来网络底层实现时序图,可以看出逻辑非常的复杂,后来我直接设计了一个新的。
    使得无论从使用上和实现上都变得无比简洁。

    [[CHELoginSingleRequest shareInstance] getSaaS30MobileRequest:api completion:completion];
    
    

    之前的API是这样的

    
        BOOL connectFlag = [self.dataConnection createHTTPFormProxyConnectionWithDictionary:urlWithAddressString
                                                                                requestDict:requestParams
                                                                              requestMethod:@"GET"
                                                                                    timeout:http_con_default_timeout
                                                                             needHSBCHeader:NO];
                                                                             
    

    回调是这样的。

    -(void) receiveResponse:(NSData *)receiveData connectId:(NSString *)connectId
    {
     ....
    }
    

    总结

    任何一个APP都可以分层为UI层,网络层,数据层
    网络层和数据层可以归结为: 数据从哪里来,又从哪里去
    UI层: 可以描述为 事件从哪里开始,又从哪里结束。

    UI 是一条明线, 数据是一条暗线。

    通常我们要做的不是理解所有的代码和具体的实现细节,而是试图理解关键的流程,以及你改动时候涉及的一部分代码实现细节, 更多的是从整体上去理解它。就像看书一样有略读和细节,先略读得到整本书初步轮廓,然后再细读你需要深入理解的地方。

    相关文章

      网友评论

          本文标题:如何快速阅读老项目,并且完成维护和少量迭代任务

          本文链接:https://www.haomeiwen.com/subject/kauszftx.html