一、类
- 类从变量开始,公共静态常量-->私有静态变量-->私有实体变量,公共函数应跟在变量列表之后。
- 类要短小,职责单一,每个类有且只有一条加以修改的理由。不能起含义模糊的词,如Processor,Manager,Super等。
- 高内聚。类中的每一个方法都应该操作一个或多个实体变量。保持函数和参数列表的短小。
- 将容易发生变化的细节隔离,使用接口和抽象类。类应该依赖于抽象,而不是具体细节。
二、系统
- 系统的构造和使用分开。即将系统的启动过程和启动后运行时的逻辑分开。
- 使用工厂模式、依赖注入将创建对象隔离。
- 最佳的系统架构由模块化的关注面领域组成(模块化+关注领域切分),每个关注面均用纯java(或其他语言)对象实现。不同的领域之间用最不具有侵害性的方面或类方面工具整合起来。这种架构能测试驱动。
- 系统需要领域特定语言。领域特定语言允许所有抽象层级和应用程序中的所有领域,从高级策略到底层细节,使用pojo表达。
- 在所有抽象层级上,意图都应该清晰可辨。
- 遵循简单设计原则:(1)运行所有测试 (2)不可重复(3)表达程序员的意图(4)尽可能减少类和方法的数量(5)以上规则按照其重要程度排列
- 规则1:TDD。
- 规则2~4: 重构,提高内聚,降低耦合,减少重复。
三、并发编程
- 分离并发相关代码和其他代码。
- 严格限制对可能被共享的数据的访问。
- 尽量缩小同步范围。
- 偶发事件的错误一定要重视,并定位问题尝试解决。
- 再创建多线程时,一定要确保非线程代码可工作且无bug。
- 线程代码需要在不同操作系统平台上进行测试,不同操作系统之间具有差异性。
四、代码味道
- 注释中不应该存在不恰当信息,冗余注释,同时注释保持简洁,字斟句酌。注释掉的代码就直接删除
- 系统构建应该由单个命令逐步构建,构建过程不应该需要一系列神秘指令或者环境依赖脚本来构建单个元素。
- 系统构建时,单个指令就可以运行全部单元测试。
- 函数不得超过3个入参。
- 如果函数非要修改某个东西的状态,就修改他的对象状态。
- 布尔参数作为flag去控制函数做不同的事,这种参数应该消灭。
- 永远不会被调用的函数应该被删除。
- 明显的行为未被实现,应修改函数行为。
- 不应该忽视代码中任何一个警告。虽然关闭警告有助于构建成功,但会陷入无穷无尽的调试和错误的风险。
- 不要出现重复代码,重复代码可以结合实际情况,使用多态,if/else, switch/case, 模板方法和策略方式解决。
- 创建分离较高层级一般性概念与较低级层级细节概念的抽象模型。创建抽象类来容纳较高层级概念,创建派生类来容纳较低层级概念,确保分离完整。所有较低层级概念放在派生类中,所有较高层级概念放在基类中。例如:只与细节实现实现有关的常量、变量和工具函数不应该放在基类中出现。基类应该对这些一无所知。
- 类中方法越少越好,函数知道的变量越少越好,类拥有的实体变量越好越好。隐藏数据,工具函数,常量,临时变量,不要创建拥有大量方法和大量实体变量的类。不要为子类创建大量受保护变量和函数。尽量保持接口紧凑,通过限制信息来控制耦合度。
- 本地变量应该正好在其首次被使用的位置上面声明,私有函数应该正好在其首次被调用的位置下面定义。垂直距离要短。
- 变量名,方法名取名要前后一致。如方法processValidationRequest,下一个方法应该取类似名字。
- 代码应具有强有力的表达力。
- 通常应该倾向于选用非静态方法,如果有疑问,就是用非静态函数。如果的确需要静态函数,确保没有机会打算让它有多态行为。
- 拒绝magic number。
- 避免否定性条件。
- 每个函数只做一件事。
- 不要继承常量,需要多处使用的常量应放在单独的class中,使用静态导入。
- 采用描述性名称。
- 方法,变量的命名应符合抽象层级。
- 使用测试覆盖工具,别略过小测试。
- 当发现某个函数有bug时,最好能编写多个测试case来尽可能的全面测试。有可能会发现bug不只一个。
- 竭尽所能使每一个测试速度够快。
网友评论