代码大全笔记

第五章软件构建中的设计

1 如果能认识到设计是一项明确的活动, 你就会获益匪浅,也就是说无论是大项目还是小项目,设计都是软件构建的一部分

5.2 关键的设计概念:    

 

最小复杂度: 应该做出简单易于理解的设计,如果你的设计方案不能让你在专注于程序的一部分时安心的忽略其他部分的话,这一设计就没有什么作用了   

易于维护     : 设计出自明的系统(self-explanatory)   

松散耦合     : 就是让程序的各个组成部分关联最小   

可扩展性     : 增强系统的功能二无须破坏它的底层结构   

可重用性     : 在其他系统中课重复使用   

高扇入         : 就是让大量的类使用某个给定的类   

低扇入         : 就是让一个类 里面少量或适中的使用其他的类   

可移植性     : 就是可以改变环境   

精简性         : 就是设计出的系统没有多余的部分,一本书的完成不在它不能在增加任何内容的时候,而是在于不能再删除任何内容的时候   

层次性         : 暂时还不能理解   

标准技术     : 尽量使用标准的语言利于共享

 

第七章 高质量的子程序

7.1


1 什么是高质量的子程序,是从分析低质量的子程序开始的,书中有例子分析,分析的几条都需要细化概念


2 创建子程序的正当理由:   

降低复杂度:

1)创建子程序最主要的一个原因就是为了降低程序的复杂度,可以通过创建子程序隐藏一些信息,即,使这些信息只在子程序中考虑,而在子程序之外的地方是不考虑的,当要编写子程序的时候要考虑他们,不过一旦程序写好了,就应该可以忘掉这些细节,可以直接调用这个子程序而无需了解其内部工作的细节,这样就达到了只专注当前考虑的程序而不被其他内容所影响,并降低了整个程序的复杂度
  
2)不需要了解细节,缩小规模,易于维护,提高正确性,当循环的嵌套过多时,就需要从子程序中提取出新的子程序来形成一个独立的子程序,这样可以降低外围子 程序的复杂度,解决嵌套的问题是看有没有php语句的高级用法可以解决嵌套的问题比如continue和break  

引入简单易懂的抽象:

就是为子程序命名一个好的变量名称,可以直观的了解你的这段程序的意图,所以说把一些功能逻辑比较复杂难于理解的代码写成子程序并赋予一个好的名字可以 直观的了解判断你实现的是一个什么功能,而暂时不用去管具体的是如何实现的,这样就有利于代码和结构上面的逻辑清晰了。  

避免代码重复:

如果在两个子程序中有类似的代码,就需要把类似的重复的代码提取出来,将其中相同的部分放在一基类,差异的放在派生类里面  

支持子类化 :

隐藏顺序:

把处理事件的顺序隐藏起来是一个很好的解决方式,一个子程序的执行不应该依赖另一个子程序是否执行,把具有相互依赖关系的语句集合起来组成子程序,这样就把必须执行的顺序隐藏在子程序中了,这样要比在系统内到处散布要好的多

隐藏指针操作 :  

提高可移植性 :  

简化复杂的布尔判断 :  

要把复杂的布尔判断放在函数中,这样可以隐藏复杂的细节,另外一个好的名字可以使程序逻辑清晰

改善性能 :

如果子程序在多处得到引用,并且此子程序可以优化,那么整个系统就会多处得到优化

确保所有的子程序都很小:

这是没有必要的

3 简单但很有必要写成子程序  166

当多处引用该子程序的时候是有必要的,或者该子程序有可能随时修改的情况下,这是需要根据具体的情况而言的

7.2在子程序层上设计
1功能的内聚性 :是最强也是最好的一种内聚性,也就是说让一个子程序仅执行一次操作,名字和功能要相对应

2 需要改变调整的其他不理想的内聚性,具体的如何修改参考书上面有例子都挺好的 168

3 编写具有功能内聚性的子程序总是可能的 ,因此要把注意力放在这个上面

7.3好的子程序的名字

1 描述子程序所作的所有事情,如果不能描述清除就不要含有副作用

2 避免使用无意义的,模糊或表述不清的动词

3 不要仅通过数字来形成不同的子程序的名字

4 根据需要确定子程序名字的长度   9--15个字符

5 给函数命名时要对返回值有所描述

6 给过程起名时要用语气强烈的动词加上宾语的形式(名词等)

7 准确使用对仗词

add/remove  increment/decrement  open/close  begin/end  insert/delete  show/hide  create/destroy lock/unlock  source/target  first/last  min/max  start/stop  get/put  next/previous  up/down   get/set
old/new

8 为常用操作确立命名规则 如id

7.4 决定子程序长度的因素:       

复杂的算法可以增加子程序的长度

子程序的内聚性,嵌套的层次,变量的数量,决策点的数量,注释数量及一些跟复杂度相关的考虑事项等

7.5 如何使用子程序参数

1 按照输入-修改-输出的顺序排列参数  : 修改就是作为输入输出的参数
2 如果几个子程序都用到一些类似的参数,应该让这些参数的排列顺序保持一致 3 使用所有的参数,去掉不使用的参数 4 把状态变量和指示发生错误的变量放在参数表的最后,因为这两个都是输出变量 5 不要把子程序的参数用作工作变量,最好是使用局部变量,就是不要用参数存储数据值,不要改变参数的值 6 子接口中对参数的假定加以说明 7 子程序的参数不应超过7个,如果超过则说明子程序之间耦合太过紧密了,应该重新设计这个子程序或这组子程序,如果你向很对不同的子程序传递相同的数据,那 就把这些子程序组成一个类,把这些经常使用的数据用作类的内部数据 8 如果你认为把输入,修改,输出参数区分开很重要那可以使用前缀 i_,m_,o_命名规则加以区分 9 为子程序传递用以维持接口抽象的变量或对象,传递的参数要足够维持子程序的稳定性,如果你经常修改参数列表,而每次修改的参数都是来自同一个对象,那就说 明你应该传递整个对象而不是个别的数据项了 10 把形式参数和实际参数对应起来避免参数放错位置 11 确保实际参数和形式参数的数据类型相一致 7.6使用函数时需要特别考虑的问题 1 什么时候使用函数什么时候使用过程  如果一个子程序的主语用途就是返回由其名字所指明的返回值,就应该是用函数,否则应该是用过程 2 设置函数的返回值 7.7  宏子程序和内联子程序      没看
第九章 伪代码编程过程

伪代码编程过程的价值重大,却很少有程序员真正挖掘出该过程的全部能量

9.1 创建类和子程序的步骤概述

1 创建类的步骤  没看

2 创建子程序的步骤 参见书 设计子程序,检查设计,编写子程序代码,检查代码

9.2 伪代码

1 项目成功的关键之一就是在代码最小的阶段扑获到错误

2 有效使用伪代码的指导原则

1)使用语句来描述特定的操作(英语和中文都可)

2)避免使用编程语言,在比代码略高的层次上设计

3)用伪代码编写你解决问题的意图,思路

4)伪代码的层次应该是仅靠在编写代码的层次之上,以便可以近乎自动地从它生成代码,应该不断的精化伪代码,加入越来越多的细节,直到看起来已经很容易直接写出代码为止

3 两个伪代码的比较 218-219

4 伪代码可以直接转化为注释,程序比较小的时候直接编程程序

5 伪代码的优势

1)使底层设计评审工作更容易,同时减少了对代码本身的进行评审的需要

2)伪代码支持反复迭代精华的思想,在不同的层次就可以发现和解决,不会产生威胁

3)伪代码使变更更加容易,在设计的最初阶段就可以发现错误和问题

4)可以使注释量减少到最小

5)伪代码比其他的设计文档更容易维护

9.3 通过伪代码编程过程创建子程序

1 设计子程序

1)检查先决条件 :检查子程序与整体设计是否相匹配,是否是必须的需求。

2)定义子程序要解决的问题:具体的实例参见书

   陈述出改子程序需要解决的问题,叙述要足够的详细以便能去创建这个子程序,需要如下条件

   a 这一子程序需要隐藏的信息

   b 传给这个子程序的各项输入

   c 从该子程序得到的输出

   d 在调用程序之前确保有关的前条件成立(初始化已经完成,输入数据的取值位于特定的范围之内)

   e 在子程序将控制权交回调用方之前,确保其后条件的成立

   看看显示错误的实例reportErrorMessage()

   . 该子程序隐藏了两项信息:错误信息的文本和当前的错误处理方式

   . 对于该子程序没有任何可保证的前条件

   . 给该子程序的输入数据是一个错误码

   . 存在两种输出:首先是错误信息,其次是reportErrorMessage()返回给调用方程序的状态值

   . 该子程序保证状态值或者为success或者为failure

3)位子程序命名

4)决定如何测试子程序,就是伪造一些合法的和不合法的参数来测试(属于单元测试,如果想了解通过先编写测试来构建程序的另一种完全不同的方法,请阅读《测试驱动开发》)

5)在标准库中搜索可用的功能:就是说在一个复杂的设计时,先看手册上面是否有合适的函数来简化你的设计,然后查看公司维护的代码库中是否有已经写好的可以提供该功能的函数,这样可以提高代码的质量和生产率

6)考虑错误处理:输入的数据和其他子程序中返回的数据

7)考虑效率问题:程序的接口是否有很好的抽象,封装是否好,算法,性能、资源与速度,记住不要在子程序上为效率白费功夫,这是需要在整体设计上考虑的事情。

8)研究算法和数据类型:在程序库中无法找到相应的内容的时候,看算法书

9)编写伪代码 :参加书上的实例,这段实例是在很高的层次上编写的

10)考虑数据:如果对数据的操作是某子程序的重点,那么就要考虑好数据的类型,清楚主要的数据部分

11)检查伪代码:复查伪代码、让别人能够理解

12)在伪代码中试验不同的想法,留下最好的,不断的精化和分解伪代码,参见书

2 编写子程序的代码步骤

1)写出子程序的说明:首先写出子程序的接口的说明,就是建立接口,变量

2)把伪代码转化为给高层次的注释 参见书,编写第一条和最后一条语句,然后转化为注释

3)在每条注释下面填充代码

221页5句话的规格说明到224页的15行伪代码到现在的长达一页的子程序,说明编码并不是一项简单的工作

4)检查代码是否需要进一步的分解:代码行过多,重构成子程序和继续递归的使用伪代码,就是说再次使用伪代码编程

3 检查代码

尽可能早的发现所有的错误

1)在脑海里检查程序的错误:就是在编译之前查看代码,在脑海里执行每一条代码路径,如果出现错误不要迷信是系统或其他原因,大部分是自己的错误

2)编译子程序:在完成以上步骤后才可以编译子程序是有效的,那种“只要在编译一次就可以搞定啦”的毛病会导致你对代码做出草率而可能带来错误的更改,从长远看这可能会花掉你更多的时间,要脱离“并凑,编译然后修改”的毛病

3)如何发挥编译子程序的功效

A 把编译器的警告级别跳到最高,通过编译器来检测错误

B 使用验证工具,FIRFOX

C 消除产生错误信息和警告的所有根源

4)在调试器中逐行执行代码:查看代码是否按照期望执行

5)测试代码:用以前编写的测试用例,参见22章和23章

6) 消除程序中的错误

4 收尾工作

按照本书说描述的优秀代码的特性来检查

具体参见书

5 根据需要重复上述的步骤

高质量的编程是一个迭代的过程,所以在程序质量不佳时,不要犹豫,把构建的工作再做一边

9.4 伪代码编程过程的替代方案

第十章 使用变量的一般事项

10.1 数据认知

1 数据认知的测试

10.2 轻松掌握变量定义

1 声明全部的变量

10.3 变量初始化原则

1 在声明变量的时候初始化

2 在靠近变量第一次使用的位置初始化,符合就近原则

3 在靠近变量第一次使用的位置声明和定义该变量

4 在类的构造函数里初始化该类的数据成员

5 检查是否需要重新初始化

6 利用警告信息

10.4 作用域

1 是变量引用局部化:就是把使用该变量的地方都集中在一起,有利于提高程序的可读性

2 尽可能的缩短变量的存活时间:变量初始化的语句和最后引用到该变量的语句之间的语句的行数应该尽可能的少

3 减少作用域的一般原则

1)在循环开始之前初始化循环当中需要用到的变量

2)知道变量即将被使用时在对其进行赋值

3)把相关的语句放在一起:如 oldnum,lodpage,...放在一起  newnum,newpage,...放在一起

4)把相关的语句组提取成单独的子程序

5)开始的时候采用最小的变量作用域,然后根据需要扩展变量的作用域

6)隐藏的信息越多,在同一时间内你需要考虑的信息就越多,犯错误的几率就越小

10.5 持续性

避免使用错误变量的步骤

1 加入调试代码或断言

2 在准备抛弃变量的时候给他们赋上“不合理的数值”

3 养成在使用所有数据之前声明和初始化的习惯

10.6 绑定时间

1 主要是考虑,变量的可替换性,当在多处都要使用某种数值的时候,最好是把这数组赋予变量,这样只要更改一处则使用这个变量的其他的地方就会都更改过来,比如,$color=#000;这是最好是把#000这个硬编码,付给一个常量。

10.8 为变量指定单一的用途

1 每个变量只用于单一用途:就是说定义变量不要重名

2 避免让代码具有隐含含义:使用两个变量来保存两种信息

3 确保使用了所有已声明的变量

 

第十一章变量命名的力量
11.1 选择好的变量名的注意事项 1  好的变量名字:要完全准确第描述出变量所代表的事物,技巧:用文字表达变量代表的是什么 2  一个好记的名字应该反应的是“什么”而不是“如何".一条员工的记录employeeData比inputRec要好,前者指向状态,后者指向计算。 3 对全局变量的命名最好是加上限定词以避免冲突,用户接口的雇员uiEmployee,数据库的雇员dbEmployee 4 把表示计算结果的变量放在最后,如total,sum,average,max,min,record,string,pointer等等这些限定词放在 最后,revenueTotal(总收入) expenseTotal(总支出),这样变量的名字就有非常优雅的对称性,某个特定的记录用index限定词表示,customerIndex(某个特 定的员工的序号) customerCount代表员工的总数 5 对仗词  begin/end  first/last  locked/unlocked  min/max  next/previous  old/new  opened/closed  visible/unvisible  source/target  source/destination  up/down 11.2 为特定类型的数据命名 1 为循环下表命名  用于简单循环之外,循环下标的命名最好是有含义的如score[teamIndex][eventIndex]  for中使用teamIndex和eventIndex 2 为状态变量命名  characterType = CONTROL_CHARACTER要比statusFlag=0x80更有意义,如果你发现需要猜测某段代码的含义时就应该考虑为变量重新命名 3为临时变量命名,就是最好是取有意义的名称 4 为布尔变量命名    典型的布尔变量名 done  error  found  success/ok   这些变量的状态要么是true要么是false, status没有明确的true和false应该使用statusOk代替,同样sourceFile应使用sourceFileAvailable或 sourceFileFound代替   使用肯定的布尔变量名  不要使用notFound之类的变量名 5 为枚举类型命名  使用前缀如Color_,Planet_,Month_来明确表示该类型成员属于同一个组 11.3 命名规则的力量 11.4 非正式命名规则 1 区分变量名和子程序名字  变量名以小写字母开始,子程序名子以大写字母开始 2 区分类和对象 通过给类型加前缀如c_区分类型和变量 3 表示全局变量 g_runningTotal 4 标示成员变量  m_ 5 标示类型声明  c_ 6 一些语言的命名规则树上有介绍 276 7 变量名包含的信息:变量的内容(代表什么),数据的种类(简单变量,类,用户自定义类),变量的作用域(使用的,包,类,全局作用域) 11.5 标准前缀 1 用户自定义类型缩写 UDT可以标识被命名对象或变量的数据类型。 参考书 2 语意前缀 他描述变量和对象是如何使用的 。 参考书 3 标准前缀的优缺点 标准化的前缀使名字变的更加紧密 例如可以用cpa而不是totalParagraphs表示段落总数,其他方面见手册 11.6  创建具备可读性的段名字 1缩写的一般指导性原则       就是采用缩写的方法有什么 参考书 消除冗余的单词,使用简短的同义词 2 避免缩写错误的规则 不要从每个单词中删除一个字符的方式来缩写 缩写要一致,不要某些地方用number,在其他的地方使用Num 创建你能读出的名字来  用 needsCompu而不用ndsCmptg 避免使用容易看错或读错的字符组合 endb  要比 bend要好 把缩写的代码建立一个文档说明即把缩写和qu 11.7 应该避免的名字 1 避免使用令人误解的名字或缩写 2 避免使用具有相似含义的名字 input和inputvalue 3 避免使用具有不同含义但名字相似的变量 clientRecs和clientReps 4 避免使用发音相似的名字  wrap和rap 5 避免在名字中使用数字  如果使用数字最好是使用数组 6 避免在名字中拼错单词 7 避免使用英语中经常拼错的单词 8 不要仅依靠大小写来区分变量名 9 避免使用多种自然语言 10 避免使用标准类型,变量,子程序的名字 11 不要使用与变量含义完全无关的名字 12 避免在名字中包含易混淆的字符  eyeChartl 和eyeCharti

 

第十二章 基本数据类型

12.1 数值概论

1 预防除零错误

2 是类型转换变的明显

3 避免混合类型的比较

4 注意编译器的警告

12.2 整数

12.3 浮点数

1 处理舍入问题:把浮点变量变成整型变量,比如用100表示美元,则0 到 99就表示美分,用函数把这个封装起来,进行换算

2 检查函数库

12.4 字符和字符串

1 突然出现的常量,最好是使用具名常量的形式,即赋值给常量,然后常量的命名带有某种含义

2 单一语言和多种语言需要考虑的字符集是ISO 8859 和unicode

12.5 布尔变量

1 用布尔变量来简化复杂的判断

如 $finished = (( elementIndex<0 ) || (MAX_ELEMENTS < elementIndex));

     $repeatedEntry = (elementIndex == lastElementIndex );

     if( finished || repeatedEntry ){   ...}

就是把相同的部分组合在一起

12.6 枚举类型

1 如果你的语言当中没有枚举类型,就使用类来代替,具体的还没有研究

12.7 具名常量

1 使用具名常量是将程序“参数化”的方法,把程序中需要变化的一方面写成参数,当需要对其进行修改的时候,只改动一处就可以了

2 任何无缘无故出现并且多处用到的字符串或数字,在使用的时候最好是都要写成具名常量的形式,易于维护

12.8 数组

12.9 创建你自己的类型

1 当在一个程序中对变量的类型具有不同的要求的时候,最好是把数据类型也定义成具名常量!

第十三章 不常见的数据类型

13.1 结构体

1 在函数中传递参数,如果参数有很多并且都是同类型的那么就把参数组合成一个函数体

13.2 指针

13.3 全局变量

1 与全局数据有关的常见问题

2 使用全局数据的理由

3 只有万不得已时才使用全局变量

4 用访问子程序来取代全局数据

1)优势:易维护,易理解,易修改

5 如何降低使用全局数据的风险

1)使用一个命名规则来突出全局变量,如在全局变量的前面加上g_

第十四章组织直线型代码
14.1 必须有明确顺序的语句 组织语句的简单原则  例子参见书 1 设法组织代码,使依赖关系变得非常明显 computeMarketingExpense()这个子程序里面不应该有初始化类的成员变量,因为这个名字和其他子程序的名字是相似的,应该重新建立 一个初始化的子程序如initializeExpenseData(),来初始化变量,这样逻辑关系使人一看就很明白要在计算子程序之前调用。 2 使子程序名能突显依赖关系 上面子程序做了两件事情那么子程序的名字就要体现两件事,应该定义成 computeMarketingExpenseAndInitializeExpenseData()看上去很太糟糕但是这个子程序的本身就很糟糕。 3 利用子程序参数明确依赖关系 有三种情况具体参见书 4 用注释对依赖关系不清的代码进行说明 尽量少使用这种方式,尽可能的使用其他的方法,先编写没有依赖关系的代码,然后再编写存在依赖关系的代码 5 用断言或错误处理代码来检查依赖关系 使用了一个判断是否初始化的例子  见书 14.2 顺序无关的语句 顺序依赖的关系确实是可以对代码的可读性,性能,可维护性有影响,当缺少顺序依赖关系时可以用第二标准来判断代码块或语句的执行顺序:就近原则,把相关的 操作放在一起。 1 是代码易于自上而下的读 不要使读者的目光跳来跳去   参看例子即可 2 把相关的语句组织在一起 一些语句之所以相关是因为他们处理了相同的数据,执行了相似的任务或者具有某种执行顺序上的依赖关系,检查方法参看书
第十五章使用条件语句
15.1 if语句 if语句遵循以下指导原则 1 首先写正常代码路径,再处理不常见情况,就是说if后接常用的代码 2 确保对等量的分支是正确的,不要使用 < 代替 <= 或 > 代替 >= 3 把正常情况的处理放在IF后面,把出错的信息处理全部放在else后面,关于如何处理嵌套参见19.4节中的减少嵌套层次的技术总结 4 让if后面跟随一个有意义的语句,不要让if后面是空的 5 考虑else语句,程序员在编写代码的时候要充分的考虑到else的情况 6 检测else语句的正确性 7 检查if..else语句是不是能反了 15.2 case语句 为case语句选择最有效的排列顺序 1 按字母或数字顺序排列各种情况 2 把正常的情况放在前面,把出错的情况放在后面 3 把使用频率高的情况放在前面 使用case语句的诀窍 1 检查每种情况对应的操作,如果比较复杂就应该写成子程序 2 不要为了使用case语句而刻意制造一个变量 3 把default子句只用于检查真正的默认情况 4 利用default子句来检查错误 5 避免代码执行超过一条case子句的末尾 case a:      statement;      statement; case b:      statement;      statement;
第十六章 控制循环
16.1 选择循环的种类 计数循环,连续求值循环,无限循环,迭代循环:对容器里面的每一个元素执行一次操作灵活度和检查位置(决定是否执行一次循环)决定了如何对用作控制结构的 循环种类进行选择 1 什么是后使用while循环 在你不知道循环要迭代多少次时就是用while循环 2 什么时候使用带退出的循环 正常的带退出循环:只看书中的例子就可以知道为什么使用带退出的循环了 好处:把所有的退出的条件放在一起,易于维护和修改,带退出循环结构要比其他的循环结构更接近人思考迭代型控制的方式 非正常的带退出循环:参见书上的例子。 3 何时使用for循环 用for循环来执行那些不需要循环内部控制的简单操作,不要通过修改下标值的方式使它终止,复杂的循环还是交给while处理比较好 4 何时使用foreach循环 适用于对数组或其他容器的各项元素执行操作 16.2 循环控制 采用两种方法阻止循环产生的错误 : 参考书 进入循环使用的指导原则 1 只从一个位置进入循环 2 把初始化代码紧放在循环的前面 3 用while(ture)表示无限循环 4 在适当的情况下多使用for循环,因为for循环把控制代码都写在顶部 5 在while循环更合适的使用不要使用for循环 处理好循环体 1 无论什么情况都要使用{ 和 } 把循环中的语句括起来 2 避免空循环:参看例子,尽量的使用易于理解的逻辑方式和简便的代码 3 把循环内务操作(i++,i=i++等)要么放在循环的开始要么放在循环的最后 4 一个循环只做一件事情 退出循环 1 设法确认循环能够终止 2 使循环终止条件看起来很明显 3 不要为了终止循环而改动for循环的下标 4 避免出现依赖于循环下标最终取值的代码 5 考虑使用安全计数器,防止循环次数过多超出正常的范围,解决出错 提前退出循环 主要讲 continue和break 检查端点 如果循环中包含了复杂的运算,那么就要手动的检查这些计算是够正确,是否愿意执行这样的检查是高效程序员和低效程序员之间的一项重要的差别 使用循环变量 1 用整数或枚举类型表示数组或循环的边界 2 在嵌套循环中使用有意义的变量名来提高其可读性(在for的嵌套下面) 3 用有意义的名字来避免循环下标串话(如重复使用i,j,k) 4 把循环下标变量的作用域限定在本循环内,就是不要在循环外部使用循环下标定义的变量 385--388没有看
第十七章 不常见的控制结构

17.1 子程序中的多个返回 多个return可以增强子程序的可读性和可维护性,同时可以避免产生很深的嵌套逻辑,但是使用的时候要多加小心

在这里衔接

例子灵活的消息格式 1 表驱动法是把逻辑和数据分开构造查询键值,可以将数据作为键值直接访问表 构造键值的方法 1 复制信息从而能够直接使用键值 0-17岁使用的是相同的费率,18-66使用的是不同的费率,66岁以上使用的是相同的费率,这样如果把age用作键值的话,那么0-17岁的费率就要 复制17边,在数组中这是不可避免的 2 转换键值以使其能够直接使用 例如max(min(66,age),17)这样就把所有小于17岁的键值转换成数组中是17的键值,把所有大于66的键值转化成数据为66创建这样的函 数,要求你能够从打算作为键值的数据中识别出某种模式来

3 把键值转换提取成独立的子程序 18.3 索引访问表 优点参见书 18.4 阶梯访问表 1 就是重新设计一种键值的读取方式,在什么范围设置什么样的键值。 2 无规则的分布的数据是不可能使用一个函数把它们整齐的转换成表键值的,这就需要是用阶梯方法 3 需要注意的细节 参见书 18.5 表查询的其他示例                                                                        

第十九章 一般控制问题

19.1 布尔表达式

1 使用ture和false做布尔判断

2 简化复杂的表达式

1)拆分复杂的判断并引入新的布尔变量

2)把复杂的表达式做成布尔函数,就是返回值是return false或return true

3)用决策表代替复杂的条件 --参见表驱动法

3 编写肯定形式的布尔表达式

1) 在if语句中,把判断条件从否定形式转化成肯定形式,并呼唤if和else字句中的代码

2) 狄摩根定理 if(!a || !b)   =》 if(!(a && b))

4 用括号使布尔表达式更清晰

5 理解布尔表达式是如何求值的 最好不要利用布尔表达式的逻辑顺序,如while($aa!=0 && $bb/$aa>1),在这里会先判断$aa是否等于零,如果为零则退出,如果不为零则进入下一个判断,这样的判断是不好的,最好是采用嵌套的判断 语句来说明你的意图

6 按照数轴的顺序编写数值表达式 应该按照这样的形式 min<i and i<max 或者 i<min or max<i 这种形式可以使代码阅读者清晰的判断出你的逻辑,而i>min and i<max 就不好

7 与零比较的指导原则是:逻辑判读是可以隐藏零,数值和字符判断是不能隐藏零,如if(!$idn){} 而 while($balance= 0){}  while(charset != "0"){}

8 布尔表达式常见的问题:在布尔判读是总是把 == 写成 = 这样在一些语言当中是不会报错的,执行的就会是赋值操作,所以为了避免这种情况,可以把变量放在右边,常量放在左边 if(CONFIND == $i),如果是老程序员就不用这样了

19.2 复合语句(语句块)

1 先写{} 2 用括号来把条件表达清楚

19.3 空语句 最好是避免使用空语句

19.4 驯服危险的深层嵌套

1 避免使用超过3到4层的嵌套

2 通过重复检测条件中的某一部分来简化嵌套的if语句,在不能无偿的减少嵌套的层次时 例如:if($a="b"){if($c="d"){if($e=f){if($g=i){//lost of code}}}}可以写成 if($a="b"){if($c="d"){}}这个执行完后if($a='b' && $c='d' && $e=f){if($g=i){//lost of code}}

3 用break块来简化嵌套语句,上面的例子可以使用break来简化,见书,php可以用do{}while(0);来执行一次代码块            

4 把嵌套的if语句使用if then else代替 一般的情况是不会出现这种深层嵌套的

5 使用case语句      

6 把深层嵌套的代码抽取出来放进单独的子程序 例子参见书

7 使用一种更面向对象的方法 这种方法没有更好的理解,找时间好好把面向对象的方式看看

8 重新设计深层嵌套的代码 复杂的代码说明你没有充分的理解你的程序,所以无法简化它,在面向对象的程序中如果有case语句就说明你没有做好分解    

9 减少嵌套层次的总结

1) 重复判断一部分条件

2) 转换成if-then-else

3) 转换成case语句

4) 把深层嵌套的代码提取成单独的子程序

5) 适用对象和多态派分

6) 用状态变量重写代码(17.3节)

7) 用防卫子句来退出子程序,从而是代码的主要路径更加清晰(17.1)

8) 使用异常(8.4节)

9) 完全重新设计深层嵌套的代码

19.5 结构化编程

1 结构化编程的核心思想是一个应用程序应该只采用一些单入单出的控制结构(见书)

2 一个结构化的程序是按照一种有序的且有规则的方式执行,不会做不可预知的跳转,可读性差意味着不容易理解,最终导致应用程序的低质量

3 结构化编程的三个组成部分

1)顺序:指一组按照先后顺序执行的语句

2) 选择:是一种有选择的执行语句的控制结构

3)迭代:是使一组语句多次执行的控制结构,常常成为循环

19.6 控制结构与复杂度

1 程序的复杂度也就是理解程序所要花费的时间,控制流程是影响复杂度的最大因素之一

2 复杂度的重要性:人的大脑是有限的不可能承受巨大的复杂度,所以在软件的编程上的错误率就会增加,所以低复杂度也是保证程序质量的重要因素之一

3 降低复杂度的一般性原则

1) 度量复杂度:在子程序中统计决策点,从1开始,遇到if、while、and、for、or的就加1,case语句中的每一种情况都加1。

2) 如何处理复杂度的度量结果 :根本的是要减少在头脑中同时考虑的项目的数量

参见书

4 其他类型的复杂度

所用的数据量,控制结构中的嵌套层数,代码行数,对用以变量的先后引用之间的代码行数(跨度),变量生存的代码行数(生存期),以及输入输出的量

第三十一章 布局与风格

31.1 基本原则

1 空白有助于人的阅读

2 着重逻辑表现

3 人看程序总是倾向于从代码的视觉外观获取提示

4 良好布局的目标

1)准确表现代码的逻辑结构

2)始终如一的表现代码的逻辑结构

3)改善可读性:合乎逻辑却很难看懂是没有任何作用的

4)经得起修改:修改某行时不必连带修改其他行代码

31.2 布局技术

1 空白

1)分组

2)空行

3)缩进

2 括号

31.3 布局风格

1 纯块结构

2 对齐结构

31.4 控制结构的布局

1 控制块结构,正确使用缩进

2 其他考虑

1)段落之间要使用空行

2)对于复杂布尔表达式,将条件分隔放在几行上

31.5 单条语句的布局

1 用空格使语句显得清楚:使逻辑表达式更容易读,使数组更容易读,使子程序参数更容易读

2 格式化后续行,就是说一行放不下代码

1)使续行明显,使用看起来是语句有明显错误的方式

如 $aaa=aaa

          +bbb+dddd

          +cccc+gggg

          +eeee+koko

          -ooo;

或使用标点符号,逻辑判断符号等等最好是放在左边

2)使逻辑更清晰,突出想要表达的内容,如变量,函数等等,常常使用的就是缩进,对齐等

3 每行只写一条语句

4 数据声明的布局

1)每行只声明一个数据

2)变量的声明应该接近首次存放的位置

3)合理组织声明的顺序,按照变量的类型组织

31.6 注释的布局

1 注释的缩进要与相应的代码保持一致

2 每行注释至少使用一个空行分开

31.7 子程序的布局

1 用空行分隔子程序的各个部分

2 将子程序的多个参数按标准缩进,分行对齐

31.8 类的布局 :没看

第三十二章 自说明代码

32.1 外部文档

1单元开发文件夹

2详细设计文档

32.2 编程风格做文档:保持好的逻辑性

32.3 注释与不注释

32.4 高校注释之关键

32.5 注释技术

1 注释单行

2 注释代码段

3 注释数据声明

4 注释控制结构

5 注释子程序

6 注释类,文件和程序

32.6    IEE标准

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值