[笔记]代码大全(一)

作者:frank 发表日期:2016-08-17 21:06:28 更新日期:2016-08-17 21:09:13 分类:猿文色

摘要

读书笔记之代码大全一。

正文

编码

把已存在的设计机械化地翻译成计算机语言

隐喻

蠕虫,病毒

风险

一个好的项目规划者能够尽可能早的将主要的风险清除掉,目前,软件开发中最常见的项目风险是糟糕的需求分析和糟糕的项目计划,因此准备工作就倾向于改进需求分析和项目计划。

架构师吃掉需求,设计师吃掉架构,程序猿则消化设计。

发现错误的时间要尽可能接近引入错误的时间。

问题定义

只说明问题是什么,不涉及解决方案。

理想的设计特征

  • 最小的复杂度,应该做出简单易于理解的设计。
  • 易于维护,为维护工作的程序员着想。
  • 松散耦合,各个组成部分的关联最小。
  • 可扩展性,增强系统功能而无须破坏底层结构。
  • 可重用性,系统的组成部分可在其他系统中复用。
  • 高扇入,大量的类使用某个给定的类,说明设计出的系统很好的利用了较低层次上的工具类。
  • 低扇入,让一个类里少量或适中的使用其他类。
  • 可移植性,方便的移植到其他系统。
  • 精简性,设计出的系统没有多余的部分。
  • 层次性,保持系统各个分解层的层次性,使得在任意的层面上观察系统,可以得到某种一致性的看法。
  • 标准技术,尽量使用标准化的常用的方法,易于别人理解。

设计层次

此处输入图片的描述

分解为i子系统

分解为子系统时,尽可能限制子系统之间的通信,简化子系统之间的交互关系,子系统之间不应有任何环形关系。

常用的子系统:业务规则,用户界面,数据库访问,对系统的依赖性。

设计构造块

启发式方法。 找出现实世界中的抽象。 封装实现细节。 当继承能简化设计时就继承。 隐藏秘密。

容易改变的区域

好的程序设计所面临的最大的挑战就是适应变化,将不稳定的区域隔离出来。好的设计要适应变化。

找出容易发生变化的区域的好办法是:首先找出程序中可能对用户有用的最小子集,这一子集构成系统的核心,不易发生改变,接下来用微小的步伐扩充这个系统。认清核心后就知道哪些组件属于附加功能,就可以提取出来。

可以工作的类

抽象数据类型(ADT ):一些数据及对这些数据操作的集合。

考虑类的一种常用方式就是把它看作是抽象数据类型再加上继承和多态两个概念。

好的抽象

  1. 类的接口应该展现一致的抽象层次,每个类只实现一个ADT。
  2. 理解类所实现的抽象到底是什么,类到底提供了哪些功能?
  3. 提供成对的服务。
  4. 把不相关的信息转移到其他类中。
  5. 尽可能让接口可编程,而不是表达语义。
  6. 谨防在修改时破坏接口的抽象。
  7. 不要添加与接口不一致的公用成员。
  8. 同时考虑抽象性和内聚性。

程序员的首要技术使命就是管理复杂度。

类关系

  1. 包含 has a。警惕有超过7个数据成员的类,如果是简单数据成员,7+2,如果是复杂数据成员,7-2。
  2. 继承 is a。派生类应该是基类的一个更为特殊的版本。对于基类中定义的所有子程序,在任何一个派生类中的含义都应该是相同的。避免让继承体系过深,2~3层。

创建类的原因

  1. 为现实世界中的对象建模。
  2. 为抽象的对象建模。
  3. 降低复杂度。
  4. 隔离复杂度。
  5. 隐藏实现细节。
  6. 限制变动的影响范围。
  7. 隐藏全局数据。
  8. 让参数传递更顺畅。
  9. 建立中心控制点。
  10. 让代码更易重用。
  11. 为程序族做计划。
  12. 把相关的操作包装在一起。
  13. 实现某种特定的重构。

子程序

内聚性:

  1. 功能的内聚性,让子程序只做一件事情。最强的内聚性。
    1. 顺序上的内聚性(上一段输出是下一段的输入),需要拆分。
    2. 通信上的内聚性(依赖相同的输入数据),需要拆分。
    3. 临时的内聚性。

避免的内聚性:

  1. 过程上的内聚性。
    1. 逻辑上的内聚性。
    2. 巧合的内聚性。

好的子程序命名

  1. 描述子程序所作的所有事情(输出结果及副作用)。
  2. 避免使用无意义的,模糊的,表达不清的动词。
  3. 对返回值有所描述。
  4. 普通函数动宾结构,对象方法不需要加入宾语。
  5. 准确使用对仗词。
  6. 为常用操作确定命名规则。

子程序的长度:150行。

子程序的参数

  • 按照输入,修改,输出的顺序排列参数。
  • 使用所有参数。
  • 把状态和出错变量放在最后。
  • 不要把子程序的参数用作工作变量。
  • 参数限制在7个以内。

函数和过程的区别

函数是指有返回值的子程序,过程是指没有返回值的子程序。如果一个子程序的主要用途就是返回由其名字所指明的返回值,那就使用函数,否则就用过程。

防御式编程

子程序不应该因为传入错误的数据而被破坏,哪怕是由其他子程序产生的数据。 最佳方式是一开始不要在程序中引入错误。使用迭代式设计、编码前先写伪代码、写代码前先写测试用例。

  1. 防止数据免遭非法输入的破坏。
  2. 使用断言。 (实现一个JavaScript断言!!) 使用断言的指导建议
  3. 用错误处理代码来处理预期会发生的状况,用断言来处理绝对不应该发生的状况。断言是用来检查代码中的bug的。
    • 避免把需要执行的代码放到断言中。
    • 对于高健壮性的代码,应该先使用断言再处理错误。

错误处理技术

  1. 返回中立值——0,空字符串,null。
  2. 返回一个错误码。
  3. 换用最接近的合法值。
  4. 调用错误处理子程序。
  5. 关闭程序。

健壮性和正确性

人身安全的软件强调正确性,消费类软件强调健壮性。

在架构阶段就要确定错误处理方式,是高层代码处理还是底层代码处理,并且始终如一的贯彻这一方法。

异常

异常是把代码中的错误或异常事件传递给调用方代码的一种特殊手段。

异常的建议:

  1. 用异常通知程序的其他部分,发生了不可忽略的错误。
  2. 只用真正例外的情况才抛出异常。
  3. 不能用异常来推卸责任。
  4. 在恰当的抽象层次抛出异常。
  5. 避免在构造函数和析构函数中抛出异常。
  6. 在异常消息中加入导致异常的全部信息。
  7. 避免使用空的catch语句。
  8. 了解所有函数库可能抛出的异常。
  9. 考虑创建一个集中的异常报告机制。

隔离部分程序,使之包容由错误造成的损害。

辅助调试代码

开发阶段可以牺牲一些速度和对资源的使用,尽早引入辅助调试代码。

进攻时编程

在开发阶段尽可能暴露出所有异常。

移除调试代码

  1. 使用构建工具。
  2. 使用内置的预处理器。
  3. 编写自己的预处理器。
  4. 使用调试存根。