一, 概述
在园子里面有很多关于各种技术细节的研究文章, 都是比较牛逼的框架研究; 但是一直没有看到关于怎么样提高开发效率的文章, 大多提高开发效率的文章都是关于自动化等方面的辅助工具类型的, 而不是开发中的一些小技巧; 今天从编码规范, 编码技巧, 开发思想, 设计模式等各方面的经验来分享如何提高开发效率.
二, 实际场景
在这个前后端分离盛行的开发年代, 分工比较明确, 开发者分前端开发者和后端开发者, 然而感到欣慰的是. net 开发者大多是担任着全栈开发的职责, 有经验的开发者都是从前端走过来的, 说白了前端业务代码对后端开发者来说那都不是事.
前后端分离前: 几年前前后端还未分离的时候, 各种前端框架还未流行的时候, 开发者的效率算是比较低下, 后端干前端的活, 甚至前端和后端夹杂工作, 导致了工作开发容易乱, 需要相互依赖, 不能完全并行工作, 这导致了开发效率底的一个极大的原因, 同时开发出来的东西体验也是很差.
前后端分离: 职责分明, 后端专注后端的开发, 前端专注前端的开发; 相互依赖关系很弱, 后端可以先定义开发接口, 前端页面及 mock 接口对接, 最后联调测试时间前后端打通过; 前后端完全可以并行开发, 开发周期缩短一倍时间; 不过这也就会导致了一个致命的问题, 大多开发者只管自己的那一部分, 不会以全局考虑, 导致的一个问题就是联调测试时间代价太大, 遇到问题相互甩锅.
前后端都存在的问题, 会再联调测试时间全部暴漏出来, 这也是为什么联调测试时间会花费那么长时间, 甚至晚上加班加点再处理问题的原因, 总结如下:
开发过程中不够谨慎, 全是空异常问题
代码不规范, 代码逻辑嵌套层次太深,
牵一发而动全身
, 以至于修改这里, 爆露出那边的问题出来, 不会适当的解耦
后端接口返回的字段含义不明确, 不清晰, 甚至完全跟字段含义违背, 比如数据库中有一个 int 类型的 Type 字段, 而前端需要类型的中文名称, 后端开发者偷懒直接用 Type 字段返回字段中文名称, 后面前端需要 int 类型的 Type 有不知道加什么字段为好, 导致修修改改, 影响效率, 下面我会具体分享细节.
眼观不足, 不会考虑后续的需求变更扩展
没有设计模式思想, 导致维护成本变大
下面从几个方面点来具体分析
三, 空异常
1.1 不可信原则
作为开发者, 你都可以把自己作为方法调用者的第三方, 不需要去关注方法的实现, 只需要关注调用方法我应该得到什么结果; 然而作为调用者第三方, 你都需要认为实现者的方法都是不可信状态, 只需要秉承该原则, 基本上你就跟空异常没有缘分了.
1.2 ?. (null 条件运算符)
先来看一下以下代码:
- [HttpGet]
- public async Task<DataResponse<bool>> GetTest()
- {
- var list = GetList();// 获取 List 列表
- if (list?.Count <= 0)
- {
- return DataResponse<bool>.AsError("没有获取到数据");
- }
- //TODO 更新操作
- return DataResponse<bool>.AsSuccess(true);
- }
上面代码很多人可能会这么写, 实际上是存在问题的 list?.Count <=0 实际上在 list 为空的时候就成了 null<=0 判断了, 则也是 false, 不符合预期结果, 正确的代码如下:
- [HttpGet]
- public async Task<DataResponse<bool>> GetTest()
- {
- var list = GetList();// 获取 List 列表
- if ((list?.Count??0) <= 0)
- {
- return DataResponse<bool>.AsError("没有获取到数据");
- }
- //TODO 更新操作
- return DataResponse<bool>.AsSuccess(true);
- }
这里就引用了?? 运算符 (空合并运算符)
1.3 ?? (空合并运算符)
MSDN 上面的解释:?? 运算符称为 null 合并运算符, 用于定义可以为 null 值的类型和引用类型的默认值. 如果左操作数不为 null, 则此返回左操作数; 否则当左操作数为 null, 返回右操作数.
1.4 如何远离空异常?
秉承原则: 不可信原则, 什么是不可信原则呢? 你调用方法都任务改方法是不可信的, 包括自己写的方法; 这在敏捷快速开发中更明显, 特别是调用团队中别人开发的微服务 API , 你不需要关注方法的实现, 只需要关注方法的结果即可, 但是也不能太过于相信它; 所有的返回结果你都需要判断是否是 null 的结果数据, 多结合?. 和?? 运算符进行合理的逻辑处理, 可以让你的项目从此远离空异常.
二, If else 解套
先来看一看比较有趣的网络上的图片
2.1 取反原则
对于上面的 if else 嵌套业务大家是不是经常遇到, 看到这种代码会非常的头疼, 难于维护, 影响开发效率, 同时也容易出现 bug.
有经验的开发者必定会对上面这段代码进行优化, 我的经验是取反原则.
什么是取反原则呢? 把不符合的条件先 return 下去, 到最后留下符合条件的逻辑, 这就是取反原则, 一眼看下来就只有一层嵌套, 不会存在多层嵌套.
我们来看下我遇到的实际场景代码, 源代码大体如下:
- if (condition)
- {
- if (condition1)
- {
- if(condition2)
- {
- if (condition3)
- {
- if (condition4)
- {
- // do something
- }
- else
- {
- // do something
- }
- }
- else
- {
- // do something
- }
- }
- else
- {
- // do something
- }
- }
- else
- {
- // do something
- }
- }
- else
- {
- // do something
- }
取反原则优化后的代码如下:
- if (!condition)
- {
- // do someting
- return;
- }
- if (!condition1)
- {
- // do someting
- return;
- }
- if (!condition2)
- {
- // do someting
- return;
- }
- if(!condition3)
- {
- // do someting
- return;
- }
- if(!condition4)
- {
- // do someting
- return;
- }
- // do someting
三, 必要的设计模式
开发过程中不要一个链路写到底, 需要把某块业务先想好, 定位明确, 该业务是应该属于哪一块, 哪一类业务, 后续可能会出现哪些方面的业务变动, 适当的引入设计模式, 那么多的设计模式, 总有一个适合你当时开发的场景;
设计模式的选取需要对该模块的作用及定义清晰, 多思考, 多归类, 自然而然心中就有了合适的设计模式的考量.
四, 必要的单元测试
做到每个方法单元测试, 最好是全路径覆盖到每一条分支的单元测试, 先从小的方法单元测试, 底层的方法单元测试通过后, 再通过 postman 或者其他工具来进行对外 API 接口层面的测试, 做到全路径覆盖的测试, 往往开发人员有一个思维就是测试正常的业务流程, 异常流程往往一概不考虑测试; 然而出问题的都是那些异常的流程, 单元测试需要遵守的原则如下:
尽可能的全路径覆盖测试
抛弃自己写的代码思维, 当一个小白进行单元测试
关注异常路径的单元测试
摒弃依赖思想, 不要依赖联调测试时间来进行测试, 往往你开发只管开发, 不管正确率, 到后续测试联调时间那就的疯狂加班加点去赶进度了, 还不能保证最佳的产品质量.
来源: https://www.cnblogs.com/jlion/p/13246527.html