开发实践思考(一)
本文内容来源平时工作中的一些思考,每一点都是实战经验,之前都是零散记录在各个文档中,是时候汇总梳理,每篇文章以10个点为准,以备记录。
1. 定义枚举变量,一定要定义无效值
定义无效值有以下好处:
- 方便有确定含义的枚举变量初始化,与正常值区分开。
- 将其他值转换为枚举类型时,如果遇到无法匹配,可转换为无效值。
2. 对成员变量的操作不建议跨层级
举个例子,一个父类的protect类型成员变量,可以在子类中进行赋值,在父类中进行使用吗?
从语法上说,是可以做到的,但从实现上看,父类的数据成员在子类中被直接改变,这是不合适的。如果跨层级直接修改,感觉父类和子类对该变量的职责各占一份,一来职责混淆,二来新增子类时,容易遗漏。如果确有场景这样操作,建议对变量进行封装,禁止子类直接,只能通过接口进行操作。
例如:网络层的响应处理中
void CNetReq:OnResponse(CResult& ret)
{
if (!ret.IsSuccess())
{
m_rspInfo.m_nRetId = ERROR;
m_rspInfo.m_nErrCode = ret.GetErrCode();
m_rspInfo.m_strErrMsg = ret.GetErrMsg();
}
OnResponse(ret);
}
上述实例代码,将网络响应包的错误处理统一提取处理,正确的处理放到OnResponse中,这就隐含了一个要求,每一个响应包的OnResponse都必须对m_rspInfo进行正确情况的赋值,而响应头m_rspInfo的默认构造是正确的,但这个约定是很脆弱的。如果新写的响应有遗漏,或者上层复用了该请求,可能会出现这样的错误,第一次响应失败,后续即使响应成功,上层也认为是失败,这是很隐蔽的问题,一定要注意。
上面还有个隐含的问题,网络层的错误信息和应用层的错误信息属于不同层级关心的事情,要有明确区分,不要混在一起处理。
3. 越是到发版前,发现的问题越多
经历过若干次发版经历后,发现上述现象。越是到发版前,发现的问题越多,感觉是不是快到每个版本的发版的deadline时,工作效率越高?
4. 版本调试级别建议至少3个
这三个级别分别是DEBUG、PRE_RELEASE、RELEASE级别:
- DEBUG级别:输出最多最详细的调试信息,辅助测试
- PRE_RELEASE级别:预发布级别,给测试用的,相比于DEBUG级别,去掉详细的调试信息,当发生严重错误时,才进行显式提示。
- RELEASE级别:生产级别,最终生产环境使用的版本,只有很少的调试信息,开启各种优化措施,提高执行效率。
在代码中,可通过_DEBUG、PRE_RELEASE宏来包裹调试代码,用于定位问题。
5. 弄清楚数值类数据内涵
要明确了解接口返回的业务数值含义,例如比例、利率等。搞清楚接口返回的是小数形式,还是百分比形式。由于不同接口是不同人开发的,有可能同一个变量,不同接口返回的形式不一样,前端展示时,不能想当然的认为是小数形式,保证显示单位和实际数值内涵保持一致。
更近一步,推荐后端在返回此类数据值,指定规则,统一按什么规则来返回,方便前端理解和使用。
6. bool变量的默认取值
针对bool类型的默认变量,本身限制了取值范围(false和true)。这种场景下,默认值取true还是false呢?
实践上看,如果该变量大部分时间为true,只有特殊场景下才会被外部设置false,那默认值取true较好,反之亦然。
7. 特别注意"错错得正"的场景
“错错得正”是自己踩过坑的场景,前端送参送错了,而后端恰好又没有关心该入参,导致最终结果虽然是对的,但从逻辑上是有隐患的。一旦后端完善此问题,那之前正常的功能可能会变得不正常,但接口描述上又没有更改,这会引发非常难以排查的问题。
在进行code review
时,排查“查交易批次号”功能,发现当前端送的参数不对时,后台也能返回正确结果,此功能早已上线,参照接口要求,该入参是必填值,询问后台开发人员得知,他们在实现该接口时,内部实现与接口描述不一致,对入参只做了简单有效性判断,具体查询逻辑没用到入参。这导致,看起来结果是对的,但前端和后端实现都有错误,这很大的隐患。
回顾这一点,要求后台接口实现人员和接口文档说明要强一致,必填的参数都要检查并且在业务逻辑中使用。
8. 接口入参转换要直截了当,不要加冗余的操作
例如某个接口的入参要传空字符串,那最佳实践就是传空字符串。在实际中,我看到有这样的代码:
char cArg = 0;
CString strArg;
strArg.Format("%c", cArg);
上述做法,乍一看,非常像传了空指针进入,再仔细一看,发现CString对于这种情况会隐含处理,显示为空字符串。这种绕圈的做法,不直观,很容易出错,不建议这样用。
入参要直接了当,要求什么类型就传什么类型,不要依赖一些转换类的隐含操作来保证。
9. 分页查询定位串问题
在涉及到大数据量查询时,常见的解决方案有分页查询。在获取定位串时,要注意获取的正确性,不要拿非定位串的字段,当做定位串字段。在这种情况下,查询小数据量是正确的,因为所有数据都小于1页的数据量。而在大数据量,且当天数据超过1页时,会出现重复同一个定位串的问题,造成重复查询。
分页查询相关问题,需要多测试几种边界值,同时做好重入查询的防范。
10. 概要设计梳理与需求紧密相关的接口信息
在接到需求以及后台接口时,需要在概要设计阶段,理清需求要求展示的每个字段的数据来源以及展示说明,有时候接口给的很多,但针对此需求,只需要关心涉及到的字段,将涉及到的字段重新整理出来,以便方便后续开发和测试。