《代码整洁之道》读后总结

一、命名规范

匈牙利命名法:变量名=属性+类型+对象描述,其中每一对象的名称都要求有明确含义,可以取对象名字全称或名字的一部分。

驼峰法:混合使用大小写字母来构成变量和函数的名字,如同驼峰一般起伏。

#### 样例 ####
# g_:全局变量
# m_:类成员变量
# s_:静态变量
# c_:常量
g_AccountMgr = None  # 全局账号管理单例
m_sAccount = ""  # 类中的账号变量

# b: bool
# i: int
# f: float/double
# lst: list
# 等等类型
lstLoginAccount = []  # 登录中账号列表
bLoginSuccess = True  # 是否登录成功

# 驼峰法。意会即可,根据自己喜好编写
PrintEmployeePaychecks();
printEmployeePaychecks();
print_employee_paychecks();

少用常量,多用赋值变量,目的是更易于查找和修改。

比如用网页请求的返回值,用变量表示之后,比起单纯的404更容易理解,而且哪些地方有这个判断,全局搜索很容易搜到,还有就是如果错误码需要修改,只需要把这个变量修改,就可以覆盖所有调用的地方了。

这种推荐在一个常量(字符串或数字都可以)有多数地方用到再用,不然会增加代码的复杂度。(一切问题都来自于系统的复杂度。 ——《人月神话》)

NOT_FOUNT_CODE = 404

 

二、函数

1)得墨忒耳定律:模块不应该了解它所操作对象的内部情况。

2)函数应该做一件事。做好一件事。只做一件事。 目的是在1条件下,调用这个代码的人理解和函数实现就会有差异,理解上的差异就是系统的bug。

3)当参数出现三个或以上的时候,考虑用数据结构。

#  基础数据结构
def Login(dData):
    sAccount, sPwd, sName, iAge = dData
#
class LoginData():
    m_sAccount = ""
    m_sPwd = ""
    m_sName = ""
    m_iAge = -1
def Login(oLoginData):
    pass

 

三、注释

  不要在工作代码注释中用签名,因为离职之后会导致这段注释的错误。不要因为个人成就感,导致代码的逐步腐烂。

 

四、格式

  C++的“剪刀原则”:所有实体变量放在类的底部。

  Java中,惯例是放在顶部。个人写代码倾向顶部。

 

五、对象与数据结构

  过程式代码(使用数据结构的代码)便于在不改动既有数据结构的前提下添加新函数。

  面向对象代码便于在不改动既有函数的前提下添加新类。

  反过来说,过程式代码难以添加新数据结构,因为必须修改所有函数。面向对象代码难以添加新函数,因为必须修改所有类。

  不要机械化的编写代码,oop并非完美,从需求出发进行设计。

 

六、错误处理

  别返回null值。

  null值导致了函数返回不同类型的数据,使用者需要小心翼翼的调用这个函数。这会导致函数中有各种判断null的逻辑,而且如果去掉了,很容易报错!

 

七、单元测试

1)需要测试用例

  测试用例可以复用,为所有维护这个模块的人使用,所以需要写测试用例,这是一劳永逸的事。

  测试用例需要跟随模块的维护而维护,因此需要遵守代码规范,而且可读性要高,然后会给后续接手的人增加额外的理解成本。

2)编写模式

  测试用例的编写模式:构造 —— 操作 —— 检验 (build - operate - check,简称BOC模式)

  每个测试用例都应该有且仅有一个断言语句。目的是可以快速定位问题,方便理解这个用例是干什么的。  

3)F.I.R.S.T规则

  快速(Fast)测试足够快。测试应该能快速运行。测试运行缓慢,你就不会想要频繁地运行它。如果你不频繁运行测试,就不能尽早发现问题,,也无法轻易修正,从而也不能轻而易举的清理代码。最终,代码就会腐坏。

  独立(Independent)测试应该项目独立。某个测试不应为下一个测试设定条件。你应该可以单独运行每个测试,以及以任何顺序运行测试。当测试互相依赖时,头一个没通过就会导致一连串的测试失败,使问题诊断变得困难,隐藏了下级错误。

  可重复(Repeatable)测试应当可在任何环境中重复通过。你应该能够在生产环境、质检环境中运行测试,也能够在无网络的列车上用笔记本电脑运行测试。如果测试不能在任意环境中重复,你就总会有个解释其失败的接口。当环境不具备时,你也会无法运行测试。

  自足验证(Self-Validating)测试应该有bool值输出。无论是通过或失败,你不应该查看日志文件来确认测试是否通过。你不应该手工对比两个不同文本文件来确认测试是否通过。如果测试不能自足验证,对失败的判断就会变得依赖主观,而运行测试也需要更长的手工操作时间。

  及时(Timely)测试应及时编写。单元测试应该恰好在使其通过的生产代码之前编写。如果在编写生产代码之后编写测试,你会发现生产代码难以测试。你可能会认为某些生产代码本身难以测试。你可能不会去设计可测试的代码。

 

八、并发模型

  生产者-消费者模型:生产的工作放入到队列中,消费者也从队列中获取工作。

  读者-作者模型:三种关系(读者与读者之间无关系,写者与写者之间互斥,读者与写者之间互斥),两个角色(读者、写者),一个场所。

  宴席哲学家(哲学家模型):单人享用,循环互斥。

 

九、死锁

  四个条件:互斥;上锁及等待;无抢先机制;循环等待。

 

十、代码草稿

  代码整洁,是一门艺术,不是一开始就能编写出整洁的代码的,需要长年累月的修正,才能得到整洁的代码。

  就像小学老师会努力让我们写作文草稿一样,这是一个逐步改进的过程。

posted @ 2020-05-22 23:48  二律背反GG  阅读(388)  评论(0编辑  收藏  举报