阅读《Code Simplicity:The Science of Software development》笔记

Posted by 启示录 Blog on May 2, 2017
  • 工程师与工程师的差别在于理解能,好工程师理解自己做的事情,差的则相反。
  • 工程师应当竭尽全力让自己的代码能够其他工程师更容易理解
  • 程序究竟是什么?

    a.给计算机的一系列指令 b.计算机依据指令进行操作
  • 每个工程师都是设计师。他们有权在自己的工作中作出良好的设计决策。
  • 软件设计的基础:定义(事物是什么)、事实(对事物的陈述)、条例(确切的建议)、规则(永远为真的事实)。
  • 软件设计是有章可循(规则)的,它们可以被认识,可以被理解。规则是永恒不变的,是基本的事实,而且确实可行。
  • 在项目延迟的情况下,增加更多的程序员,很可能加剧延迟(了解需求,分析这些都需要时间)
  • 软件的科学分为两种:软件管理的科学、软件设计的科学
  • 软件的目标:帮助他人,而不是增加他人的麻烦。
  • 一个人写出优秀软件的潜力,完全取决于他在多大程度上理解了“帮助他人”的意思.
  • 软件设计科学的目标也是帮助用户解决问题

    1
    2
    3
    
      a.确保软件能尽可能提供多的帮助
      b.确保软件能持续提供尽可能多的帮助
      c.设计工程师尽可能简单地开发和维护的软件系统,这样的系统才能为用户提供尽可能多的帮助,而且能持续提供尽可能多的帮助
    
  • 软件设计的公式:D=V/E.

    1
    2
    3
    
      D表示这个变化(需求)的合意程度
      E完成这个变化(需求)所需要的成本
      V表示这个变化(需求)所带来的价值(这个变化能带来多大的帮助)
    

    根据公式可以得出任何一点改变,其合意度与价值成正比,与成本成反比。

成本包括:实现成本(E1)和维护成本(E2)
1
2
3
4
	价值包括:当前价值(V1)和未来价值(V2) - 演变后的软件设计公式:D=(V1+V2)/(E1+E2),最终我们考虑的是未来价值和维护成本。D=V(f)/E(m) - 在成本上,降低实现成本,往往降低维护成本更重要 - 软件设计质量的好坏,正比如改软件在未来能持续帮助他人的时间长度 - 不可预测的未来

	a.未来的某些事情,我们是所不知道的
	b.工程师最常犯,也是最严重的错误就是其实不知道未来的时候去预测未来
  • 软件设计的目的是创造更好的未来(提升价值,降低维护成本)
  • 软件开发的三大误区:

    1
    2
    3
    
      a.编写不必要的代码
      b.代码难以修改 (对未来做太多假设)
      c.过分追求通用(对未来做太多假设)
    

    不要编写不必要的代码,并且要删除没有用到的代码

  • 设计程序时,应当根据你现在确切知道的需求,而不是你认为未来会出现的需求。但是也的站在用户的角度去思考,不要自己认为重要,用户也会觉得重要。
  • 在程序中新增缺陷的可能性与代码修改量成正比。
  • 最好的设计就是要尽可能适应外界尽可能多的变化,而软件自身的变化要尽可能少。
  • 永远不要“修正”任何东西,除非它真的有问题,而且有证据表明问题确实存在的。(并不是永远一层不变,我们在开发发布软件时可以使用一些方法来解决这样的问题,例如灰度发布,A/B测试)
  • 理想情况下,任何系统里的任何信息,都应当只存在一次。(这就是为什么要对经常使用,但是又重复的代码需要进行简单的封装来提高质量与可读性,import,include,call…etc)
  • 软件的维护难度,反比于该部分的简洁程度。(如何别人的代码写的足够简单,那么后面维护的人也足够的轻松。如果你恨一个人,你就把你的代码写的晦涩难懂就可以了).
  • 代码的可读性取决于字母和符号之间的空白排布(利用换行来区分代码块)
  • 命名应当足够长,能够完整的表达其意义或描述其功能,但是不能太长,以免影响阅读(eg:getUserById vs fetchUserInformationViaUserId)
  • 简洁离不开设计(例如某个处理方式可以通过某种设计模式来简化代码复杂度)。
  • 简洁是相对。(例如会计用的系统,医疗人员不一定会使用)。
  • 如何才能有效的“增加”复杂度?

    1
    2
    3
    4
    5
    6
    7
    
      a.扩展软件用途(没有必要一下子考虑完整,要迭代!)
      b.新增程序员(优秀与已经了解需求的除外)
      c.做无谓的改变(现实生活中有很多改变都是产品经理臆想)
      d.困于糟糕的技术。(主要还是学习能力的问题,不敢跳出自己的的舒适编程语言区,就好比用PHP做异步和NodeJs做异步)
      e.理解错误(做之前要先问自己是否理解接下来的工作究竟是做什么)
      f.糟糕的设计或不做设计(一边行动的时候,一边做设计会让人局限于某个圈子)
      g.重新发明轮子。 (不过对于学习者,造轮子是进步最快的。)
    
  • 糟糕的技术:选择技术的三点(拓展眼界很重要,否则选择总只有几个,选择不好,受累的是开发人员。Hacker News、RSS、Medium、湾区日报、Github、ProductHunt…etc)

    1
    2
    3
    
      a.是否可持续更新
      b.互通性。(例如数据库的选择,究竟是Mongodb还是MySQL还是PostgreSQL)
      c.作者对品质的重视度 (技术的质量,例如代码质量)
    
  • 大多数麻烦的设计问题,都可以用在纸上画图或写出来的办法找打答案
  • 面对复杂的设计。首先要画出主体,然后拆分主体为小部分。完成各个小部分的设计。最后组装起来
  • 重构(重写),首先重构是前面设计者的失败的结果。:

    1
    2
    3
    4
    5
    
      a.完成准确的评估。证明重写整个系统比重新设计现有的系统更有效率
      b.有足够的时间来开发新系统.
      c.你要比原有系统的设计师更高明,或者原有系统是你设计,但现在你的设计能力已经大大提高
      d.自己已经决定通过一系列简单的步骤设计整个系统
      e.拥有足够的资源,在可以维护老系统的同时可以开发新系统
    

只有当以上条件都满足时才能去做重构。否则只能通过改进旧系统解决问题。

  • 对软件的了解程度,取决于自己真正测试它的程度
  • 除非亲自测试过,否则你不知道软件是否能正常运行(自己测试过后交付是负责任的表现)