`
足至迹留
  • 浏览: 485331 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

<2> 注释,格式,错误处理,单元测试,类,系统

 
阅读更多
上面一篇主要说了如何写出整洁干净的函数,单一职责,短小,不重复等。下面继续后续内容。

三、 注释
亲身体会,这是一个纠结争议的问题。注释多了好还是少好?注释能比代码更精确吗?代码能让人一目了然吗?

注释的恰当使用是为了弥补我们用代码表达意图时遭遇的失败。注释总是一种失败,太多的注释并不值得庆贺。因为注释会撒谎,代码在变动在演进,程序员不能坚持维护注释。只有代码是真实的。记得同事郜代表的名言“代码是不会骗人的!”,如雷贯耳。

有些注释是必要的,也是有利的。
好注释:
1) 法律信息。比如类开头的一些Copyright…
2) 对意图的解释
3) 警示,提醒
4) 公共api中的javadoc,这个相信大家体会很深,没有详细的jdk的javadoc我们很难使用它们。但这个javadoc需要精确,长期的维护,以免误导或错误。

坏注释
1)所谓每个函数都要有javadoc或每个变量都要有注释的规矩是愚蠢可笑的,同意啊!!

2)不需要类似修改记录一样的注释,我们有代码管理工具,历史信息可以查看。
3)注释掉的代码不需要保留,直接删掉。我们的代码库可以查到历史记录。

短函数不需要太多描述,给短函数取个好名字比注释好的多


四、 格式

代码格式关乎沟通,沟通是开发者之间的头等大事,项目组至少要采取统一的格式要求,比如缩进,变量定义,空行等。团队制定的规则,所有人都要遵守。

适当的空行可以让读者对独立的逻辑块一目了然。
变量尽可能在靠近使用的地方定义,循环变量总要在循环体里定义。
相关函数调用,同一个类中调用者尽可能在被调用者前面。
概念相关的函数尽可能靠近。

五、 对象和数据结构
对象和数据结构是抽象的结果。对象对外隐藏数据暴露行为,数据结构对外暴露数据,几乎没有行为,数据结构很适合传送数据,比如作为方法参数,成员变量。两者可以综合考虑使用。
使用对象尽量遵循“最少知识原则”不要链式调用,如a.getB().getC().getD();
可以看B,C,D是否可以转为纯数据结构被包含在A中,可以a.b.c.d的使用,不违反Demeter原则。这点可以放个疑问,貌似这样实现也不怎么优雅??

六、 错误处理

不要因为错误处理而搞乱了正常代码逻辑。
1. 使用异常而非返回码
2. 使用不可控异常

这一点还是值得讨论的,检查异常和非检查异常各有用处。《clean code》作者认为检查异常破坏了开闭原则,当底层的方法修改,增加了一个检查异常则所有调用到这个方法的地方都要增加异常的捕获。但是也不至于底层一个小小的异常就直接导致程序终止吧,比如数据库里查出的一个值格式不正确此时可以采取很多处理,比如给个默认值等等,依场景而定。所以这点还是搁置吧,具体问题具体分析。

3. 别返回null值。
如果一个方法可能返回null值,则在调用的地方会有很多的if(obj != null),一处不判断就有可能抛出个空指针,也导致代码很脏,这点深有体会,也曾经全员整改过返回null值的情况,比如返回list的方法可以把null改为空的list。

4. 别传递null值
传入null值在方法刚开始还是要判断null值。但如果是对外提供api,那没办法了,必须判断,谁知道调用者传过来的是什么呢?

七、 单元测试
单元测试也应跟生产代码一样整洁,测试代码也必须要维护。
关于单元测试的标准可以参考其他书籍,比如junit的标准,独立,可重复等。每个单元测试只测试一个功能。

关于TDD本人一直觉得有个很大的问题,单元测试要在什么层次做?每个方法都要?这样重构时会有很大的麻烦,任何一个方法的改动都会导致大片的ut失败,难道这就是目的?要行覆盖? 本人所待过的项目组的原则是在业务层面ut,保证功能,当然这会有遗漏,但本人还是很赞同的。大家怎么看呢?


八、 类
1.类应该短小
类的第一规则就是应该短小,第二规则就是要更短小。是的,跟函数看起来一样,但短小的定义不一样。函数的短小是以代码行数衡量(原书话语,个人认为行数只是一方面,其实跟类也是一样,权责也要小,就是单一权责嘛),但类的短小是权责,不要上帝类。
和函数一样,当命名觉得不太好涵盖类的功能时,就是类的权责太多了。
1)单一权责原则(SRP)
系统应该由许多短小的类而不是少量巨大的类组成。每个小类封装成一个权责单一的类,并与少数其他类一起协同达成期望的系统行为。
2)内聚
类应该只有少量实体变量,并且类中的每个方法都应该操作一个或多个这种变量。方法操作的变量越多,则此方法跟类的关系越内聚。
3)保持内聚性就会得到许多短小的类

2.为了修改而组织,要符合开闭原则

九、 系统层级
一个系统肯定会有很多模块,要有负责全局的,有负责细节的,抽象层级和实现层级不能混乱,保持系统的整洁。

每个应用程序都应该关注起始过程。如,对象的初始化。
Public Service getService()
{
If(null == service)
{
    Service = new MyService(…);
}

Return service;
}

这就是所谓的延迟初始化,也有一定的好处。然而也遇到了问题,依赖了MyService的实现,硬编码。
这种情况出现在一处也不会有太大问题,当系统中多次出现时就会造成缺乏模块组织性,甚至重复代码。个人认为这点不是很绝对,延迟加载也是有好处的,核心是不要造成系统组织混乱就可以了。

1. 工厂
使用工厂模式方法构造对象,让使用的模块不用担心创建。

2. 依赖注入
这是一种强大的将构造和使用分离的策略,由容器去管理对象的生命周期。

3. 代理模式和AOP
当一些横切事务需要统一处理,如日志,性能统计,事务处理等横切功能可以统一使用aop方式管理。

4. 不要过度设计

十、 迭进
通过迭进设计达到整洁目的。
前面就说过,整洁的代码不是第一稿就能写出来的,写完一稿要经过重构。

Kent Beck(极限编程创始人之一)关于简单设计有四个原则,对于创建具有良好设计的软件有莫大的帮助。
1) 运行所有测试
2) 不可重复
3) 表达程序员的意图
4) 尽量减少类和方法的数量
这四点重要性从上到下减小,实践时可以根据情况排序。

被无数次强调的原则就是测试是重构的前提。没有用例不要重构!当然不能没有用例。

重复是一切坏味道的起源。最简单的重复形式是代码块一样或及其相似,还有功能很相似的方法。方法抽取,或提升公共方法到父类是常用的方法,模板方法模式是一种移除高层级重复的通用技巧。

表达力就可以按上面讲的准确的命名,短小的函数来达到表达自己要完成的功能或设计,比如类名中包含Command或Visitor。

尽可能少的类,重要性会排在最后面,一般这种情况发生是因为教条式的分解方法或类导致,比如为每个类创建接口。
0
1
分享到:
评论

相关推荐

    Python 2.5

    还有一些有趣的比如说,象下面的一个比较处理,用C语言为: &lt;br/&gt;&lt;br/&gt; &lt;br/&gt;&lt;br/&gt;if (2&lt;br/&gt;&lt;br/&gt;用Python可以表示为&lt;br/&gt;&lt;br/&gt;if (2 &lt;br/&gt;&lt;br/&gt; &lt;br/&gt;&lt;br/&gt;什么是Zope? &lt;br/&gt;&lt;br/&gt; &lt;br/&gt;&lt;br/&gt;Zope是一个开放源代码...

    计算机科学与教育技术:使用C/C++进行高效学生成绩管理系统的设计与实现

    优化一个C/C++课程设计项目,如学生成绩管理系统,通常涉及以下几个方面: 代码结构优化:确保代码模块化,...测试:进行彻底的测试,包括单元测试、集成测试和系统测试。 部署:确保系统能够在目标环境中稳定运行。

    语言程序设计课后习题答案

    C++是一个更好的C,它保持了C的简洁、高效、接近汇编语言、具有良好的可读性和可移植性等特点,对C的类型系统进行了改革和扩充,因此C++比C更安全,C++的编译系统能检查出更多的类型错误。 C++语言最重要的特点是...

    matlab终止以下代码-cuDebye:从原子模型评估粉末衍射图的快速实验cuda程序

    matlab终止以下代码cuDebye版本1.5 一种快速的实验性Cuda例程,用于从原子模型评估粉末衍射图。...该程序已在以下图形处理单元(GPU)上进行了广泛的测试:GTX 970,GTX 980TI和GTX 1080 该程序只能使用一个G

    C#微软培训资料

    &lt;&lt;page 2&gt;&gt; page begin==================== 7.5 逻辑操作符和逻辑表达式.68 7.6 位 运 算 .69 7.7 其它特殊操作符 .72 7.8 小 结 .77 第八章 流 程 控 制 .79 8.1 条 件 语 句 .79 8.2 循 环 语 句 ....

    Eclipse插件开发-测试用例自动生成工具.zip

    测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化...

    软件资料文档标准规格

     ◇ 测试分析报告:测试工作完成以后,应提交测试计划执行情况的说明,对测试结果加以分析,并提出测试的结论意见。  ◇ 开发进度月报:该月报系软件人员按月向管理部门提交的项目进展情况报告,报告应包括进度...

    突破程序员基本功的16课.part2

    16.2.2 单元测试的逻辑覆盖 16.2.3 JUnit介绍 16.2.4 JUnit的用法 16.3 系统测试和自动化测试 16.3.1 系统测试概述 16.3.2 自动化测试 16.3.3 常见自动化测试工具 16.4 性能测试 16.4.1 性能测试概述 ...

    计算机二级公共基础知识

    若k&gt;1,则该结点的父结点编号为INT(k/2); ② 若2k≤n,则编号为k的结点的左子结点编号为2k;否则该结点无左子结点(显然也没有右子结点); ③ 若2k+1≤n,则编号为k的结点的右子结点编号为2k+1;否则该结点无右...

    基于javaweb的小型超市信息管理(进销存)系统。开发工具为MyEclipse.zip

    测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化...

    华为编程开发规范与案例

    可测试性问题(D类)-指设计、编码中因考虑不周而导致后期系统可测试性差的问题。  处罚办法 问题发生率: P=D/S D=DA+0.5DB+0.25DC 其中: P -问题发生率 D -1个季度内错误总数 DA -1个...

    Android library 工具类、日常开发整理.zip

    测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化...

    工具箱(java开发中常用工具类,web工程中常用的Filter等).zip

    测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化...

    Android开发常用工具类,让程序猿有更多时间看电影,撩妹纸。.zip

    测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化...

    代码语法错误分析工具pclint8.0

    使用PC-Lint在代码走读和单元测试之前进行检查,可以提前发现程序隐藏错误,提高代码质量,节省测试时间。并提供编码规则检查,规范软件人员的编码行为。 由于PC-LINT对于一般程序员来说可能比较陌生,有好多人安装...

    Java后端开发库,涵盖:常用工具类、SPI扩展、分布式锁、限流、分布式链路追踪等。.zip

    测试框架和工具则协助开发者编写和运行单元测试、集成测试及性能测试,确保软件质量。 版本控制与协作: 通过集成Git、SVN等版本控制系统,支持团队成员间的代码共享、分支管理、合并请求和冲突解决。 可视化...

Global site tag (gtag.js) - Google Analytics