一、命名规范
匈牙利命名法:变量名=属性+类型+对象描述,其中每一对象的名称都要求有明确含义,可以取对象名字全称或名字的一部分。
驼峰法:混合使用大小写字母来构成变量和函数的名字,如同驼峰一般起伏。
#### 样例 #### # 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)测试应及时编写。单元测试应该恰好在使其通过的生产代码之前编写。如果在编写生产代码之后编写测试,你会发现生产代码难以测试。你可能会认为某些生产代码本身难以测试。你可能不会去设计可测试的代码。
八、并发模型
生产者-消费者模型:生产的工作放入到队列中,消费者也从队列中获取工作。
读者-作者模型:三种关系(读者与读者之间无关系,写者与写者之间互斥,读者与写者之间互斥),两个角色(读者、写者),一个场所。
宴席哲学家(哲学家模型):单人享用,循环互斥。
九、死锁
四个条件:互斥;上锁及等待;无抢先机制;循环等待。
十、代码草稿
代码整洁,是一门艺术,不是一开始就能编写出整洁的代码的,需要长年累月的修正,才能得到整洁的代码。
就像小学老师会努力让我们写作文草稿一样,这是一个逐步改进的过程。