构建之法——读书笔记(2)

此次学习主要记录概念型知识点,摘抄如下:

第三章 软件工程师的成长

个人能力的衡量与发展

软件系统的绝大部分模块都是由个人开发或维护的。在软件工程的术语中,我们把这些单个的成员叫做Individ-ual Contributor(IC)。IC在团队中的流程是怎么样的呢?以开发人员为例,流程如下。

  • 通过交流、实验、快速原型等方法,理解问题、需求或任务

  • 提出多种解决办法并估计工作量

  • 其中包括寻找以前的解决方案,因为很多工作是重复性的

  • 与相关角色交流解决问题的提案,决定一个可行的方案

  • 执行,把想法变成实际中能工作的代码,同时验证方案的可行性和其他特性(例如程序的效能等)

  • 和团队的其他角色合作,在测试环境中测试实现方案,修复缺陷(Bug)。如果此方案有严重的问题,那么就考虑其他方案

  • 在解决方案发布出去之后,对结果负责每个人的工作质量直接影响最终软件的质量

初级软件工程师成长阶段

1. 积累软件开发相关的知识,提升技术技能(如对具体技术的掌握,动手能力)

2. 积累问题领域的知识和经验(例如:对医疗或金融行业的了解)

3. 对通用的软件设计思想和软件工程思想的理解

4. 提升职业技能(区别于技术技能)
职业技能包括:自我管理的能力,表达和交流的能力,与人合作的能力,按质按量完成任务的执行力,这些能力在IT行业和其他行业都很重要。

5. 实际成果

软件开发的工作量和质量的衡量标准

    • 项目/任务有多大?
      说明项目的大小,一般用代码行数(Line Of Code,LOC)来表示;也可以用功能点(Function Point)来表示

    • 花了多少时间?
      可以用小时、天、月、年来表示。一组人所花费的时间可以用(人数×时间)来表示,例如某项目花费了10个人×月

    • 质量如何?交付的代码中有多少缺陷?
      交付有两个定义

      • 在代码完成(Code Complete)时,交付给测试人员
      • 在软件最终发布时,交付给顾客可以用缺陷的数量来除以项目的大小。
    • 是否按时交付?
      在团队工作中,稳定、一致的交付时间是衡量一个员工能力的重要方面

第四章 两人合作

①代码规范

每个人对于什么是“好”的代码规范未必认同,这时我们很有必要给出一个基准线—什么是好的代码规范和设计规范

计算机只关心编译生成的机器码,你的程序采用哪种缩进风格,变量名有无统一的规范等,与机器码的执行无关。但是,做一个有商业价值的项目,或者在团队里工作,代码规范相当重要。“代码规范”可以分成两个部分:

1. 代码风格规范——主要是文字上的规定,看似表面文章,实际上非常重要

2. 代码设计规范——牵涉到程序设计、模块之间的关系、设计模式等方方面面的通用原则

② 代码风格规范

代码风格的原则是:简明易读无二义性
提示:这里谈的风格是一家之言,如遇争执,关键是要本着“保持简明,让代码更容易读”的原则,看看争执中的代码规范能否让程序员们更好地理解和维护程序

2.1 缩进

是用Tab键好,还是2、4、8个空格?
结论4个空格,在Visual Studio和其他的一些编辑工具中都可以定义Tab键扩展成为几个空格键。不用Tab键的理由是,Tab键在不同的情况下会显示不同的长度,严重干扰阅读体验。4个空格的距离从可读性来说,正好

2.2 行宽

行宽必须限制,但是以前有些文档规定的80字符行宽太小了(以前的计算机/打字机显示行宽为80字符),现在时代不同了,可以限定为100字符

2.3 括号

在复杂的条件表达式中,用括号清楚地表示逻辑优先级

2.4 断行与空白的{ }行

1. 最精简的格式A:

if (condition)  DoSomething(); 
else    DoSomethingElse();
优点:因为可以节省几行 缺点:不同的语句(Statement)放在一行中,程序调试(Debug)起来非常不方便,如果要一步一步观察condition中各个变量(condition可能是包含函数调用的复杂表达式)的变化情况,单步执行就很难了

2. 有断行的格式B:
if (condition)
    DoSomething(); 
else 
    DoSomethingElse();
缺点:由于没有明确的“{”和“}”来判断程序的结构,在有多层控制嵌套时,这样的格式就不容易看清结构和对应关系

3. 改进的格式C
if (condition) {
    DoSomething(); 
} else {
    DoSomethingElse();
}

缺点:不够清晰

4. 每个“{”和“}”都独占一行,即格式D
if (condition) 
{ 
    DoSomething(); 
} 
else 
{ 
    DoSomethingElse(); 
}

2.5 分行
不要把多条语句放在一行上
a =1; b =2;      // bogus
if (fFoo) Bar();   // bogus

更严格地说,不要把多个变量定义在一行上
Foo foo1, foo2;    // bogus
2.6 命名
用单个字母给有复杂语义的实体命名并不可取,也是经过了实践检验的方法叫“匈牙利命名法”。例如:
fFileExist  // 表明是一个bool值,表示文件是否存在;
szPath  // 表明是一个以0结束的字符串,表示一个路径

2.7 下划线

下划线用来分隔变量名字中的作用域标注和变量的语义,如:一个类型的成员变量通常用m来表示,或者简单地用一个下划线“”来做前缀。移山公司规定下划线一般不用在其他方面

2.8 大小写

由多个单词组成的变量名,如果全部都是小写,很不易读,一个简单的解决方案就是用大小写区分它们。

  • Pascal——所有单词的第一个字母都大写
  • Camel——第一个单词全部小写,随后单词随Pas-cal形式,这种方式也叫lowerCamel

一个通用的做法是:

  • 所有的类型/类/函数名都用Pascal形式,所有的变量都用Camel形式
  • 类/类型/变量:名词或组合名词,如Member、ProductInfo等
  • 函数则用动词或动宾组合词来表示,如get/set、RenderPage()

2.9 注释

需要注释什么?不要注释程序是怎么工作的(How),程序本身就应该能说明这一问题

//this loop starts the i from0 to len, in each step, it
// does SomeThing
for (i =0; i < len; i++)
{
    DoSomeThing();
}

以上的注释是多余的。注释是为了解释程序做什么(What),为什么这样做(Why),以及要特别注意的地方,如下
/go thru the array, note the last element is at [len-1]
for (i =0; i < len; i++)
{
    DoSomeThing();
}

复杂的注释应该放在函数头,很多函数头的注释都用来解释参数的类型等,如果程序正文已经能够说明参数的类型in/out,就不要重复!
注释也要随着程序的修改而不断更新,一个误导的(Misleading)注释往往比没有注释更糟糕
另外,注释(包括所有源代码)应该只用ASCII字符,不要用中文或其他特殊字符,否则会极大地影响程序的可移植性。
在现代编程环境中,程序编辑器可以设置各种美观得体的字体,我们可以使用不同的显示风格来表示程序的不同部分。

注意:有些程序设计语言的教科书对于基本的语法有详细的注释,那是为了教学的目的,不宜在正式项目中也这么做

3. 代码设计要规范
4. 代码复审
正确定义:看代码是否在“代码规范”的框架内正确地解决了问题

软件工程中最基本的复审手段,就是同伴复审

1. 代码复审的目的在于

  • 找出代码的错误,比如:

    • 编码错误,比如一些碰巧骗过了编译器的错误

    • 不符合团队代码规范的地方

  • 发现逻辑错误,程序可以编译通过,但是代码的逻辑是错的

  • 发现算法错误,比如使用的算法不够优化,边界条件没有处理好等

  • 发现潜在的错误和回归性错误—当前的修改导致以前修复的缺陷又重新出现

  • 发现可能需要改进的地方

  • 教育(互相教育)开发人员,传授经验,让更多的成员熟悉项目各部分的代码,同时熟悉和应用领域相关的实际知识

结对编程

结对编程的优势
  1. 在开发层次,结对编程能提供更好的设计质量和代码质量,两人合作解决问题的能力更强

  2. 对开发人员自身来说,结对工作能带来更多的信心,高质量的产出能带来更高的满足感

  3. 在企业管理层次上,结对能更有效地交流,相互学习和传递经验,分享知识,能更好地应对人员流动

总之,如果运用得当,结对编程可以取得更高的投入产出比(Return of Investment)

 
 
posted @ 2017-04-14 15:03  Rylee  阅读(119)  评论(0编辑  收藏  举报