zoukankan      html  css  js  c++  java
  • 【连载】优秀程序员的45个习惯之35

    对问题各个击破

    ——  高效程序员的 45 个习惯之习惯35

    “逐行检查代码库中的代码确实很令人恐惧。但是要调试一个明显的错误,只有去查看整个系统的代码,而且要全部过一遍。毕竟你不知道问题可能发生在什么地方,这样做是找到它的唯一方式。”
     

     单元测试(在第 76 页,第 5 章)带来的积极效应之一,是它会强迫形成代码的分层。要保证代码可测试,就必须把它从周边代码中解脱出来。如果代码依赖其他模块,就应该使用 mock 对象,来将它从其他模块中分离开。这样做不但让代码更加健壮,且在发生问题时,也更容易定位来源。

     

    否则,发生问题时有可能无从下手。也许可以先使用调试器,逐行执行代码,并试图隔离问题。也许在进入到感兴趣的部分之前,要运行多个表单或对话框,这会导致更难发现问题的根源。你会发现自己陷入整个系统之中,徒然增加了压力,而且降低了工作效率。

     

    大型系统非常复杂 —— 在执行过程中会有很多因素起作用。从整个系统的角度来解决问题,就很难区分开,哪些细节对要定位的特定问题产生影响,而哪些细节没有。

    答案很清晰:不要试图马上了解系统的所有细节。要想认真调试,就必须将有问题的组件或模块与其他代码库分离开来。如果有单元测试,这个目的就已经达到了。否则,你就得开动脑筋了。

     

    比如,在一个时间紧急的项目中(哪个项目的时间不紧急呢 ) FredGeorge 发现他们面对的是一个严重的数据损毁问题。要花很多精力才能知道哪里出了问题,因为开发团队没有将数据库相关的代码与其他的应用代码分离开。他们无法将问题报告给软件厂商,当然不能把整个代码库用电子邮件发给人家!

     

    于是,他们俩开发了一个小型的原型系统,并展示了类似的症状;然后将其发送给厂商作为实例,并询问他们的专家意见,使用原型帮助他们对问题理解得更清晰。

     

    而且,如果他们 无法 在原型中再现问题的话,原型也可以告诉他们可以工作的代码示例,这也有助于分离和发现问题。

     

    识别复杂问题的第一步,是将它们分离出 来。既然不可能在半空中试图修复飞机引擎,为什么还要试图在整个应用中,诊断其中某个组成部分的复杂问题呢?当引擎被从飞机中取出来,而且放在工作台上之 后,就更容易修复了。同理,如果可以隔离出发生问题的模块,也更容易修复发生问题的代码。

     

        分离原型                          Prototype to isolate

     

    可是,很多应用的代码在编写时没有注意到这一点,使得分离变得特别困难。应用的各个构成部分之间会彼此纠结:想把这个部分单独拿出来,其他的会紧随而至。 在这些状况下,最好花一些时间把关注的代码提取出来,而且创建一个可让其工作的测试环境。

     

    对问题各个击破,这样做有很多好处:通过将问题与应用其他部分隔离开,可以将关注点直接放在与问题相关的议题上;可以通过多种改变,来接近问题发生的核心— —你不可能针对正在运行的系统来这样做。可以更快地发现问题的根源所在,因为只与所需最小数量的相关代码发生关系。

     

    隔离问题不应该只在交付软件之后才着手。在构建系统原型、调试和测试时,各个击破的战略都可以起到帮助作用。

     

    对问题各个击破
    在解决问题时,要将问题域与其周边隔离开,特别是在大型应用中。

     切身感受

    面对必须要隔离的问题时,感觉就像在一个茶杯中寻找一根针,而不是大海捞针。

    平衡的艺术

    • 如果将代码从其运行环境中分离后,问题消失不见了,这有助于隔离问题。
    • 另一方面,如果将代码从其运行环境中分离后,问题 还在 ,这也有助于隔离问题。
    • 二分查找 的方式来定位问题是很有用的。也就是说,将问题空间分为两半,看看哪一半包含问题。再将包含问题的一半进行二分,并不断重复这个过程。
    • 在向问题发起攻击之前,先查找你的解决问题日志(见第 129 页上的习惯 33 )。



    ---------------------------------------------------------------------------------------
    1.诚邀合作: 如果您想翻译、写作或是推荐IT类图书,我们将竭诚为您提供最专业的服务平台。
    2.联系我们: yuany@turingbook.com(E-Mail)
    3.欢迎加入图灵社区与作译者、业内人士进行交流:

    http://www.ituring.com.cn/article
  • 相关阅读:
    字符编码相关
    函数之形参与实参
    文件操作模式
    函数对象,名称空间,作用域,和闭包
    吴裕雄天生自然SPRINGBOOT开发实战处理'spring.datasource.url' is not specified and no embedded datasource could be autoconfigured
    吴裕雄天生自然SPRINGBOOT开发实战处理XXXX that could not be found.
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot HTML表单登录
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot REST示例
    吴裕雄天生自然SpringBoot开发实战学习笔记处理 Could not write metadata for '/Servers'.metadata\.plugins\org.eclipse.core.resources\.projects\Servers\.markers.snap (系统找不到指定的路径。)
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot Tomcat部署
  • 原文地址:https://www.cnblogs.com/turingbooks/p/1624593.html
Copyright © 2011-2022 走看看