关于软件开发习惯和规范的一点思考
软件开发是一种工程问题,毕竟,软件是用来解决业务问题的,科技不是目的,我们产出的价值不是代码,而是收益,就是说,我们被雇佣是来降低成本提升收益的,所做工作的都是为了实现业务,解决问题,这就是程序员存在的意义,当然这是对公司来说的,对程序员自身来说,我们需要为自己选择一条合适的发展方向,不断提升自己,保持行业竞争力。
关于编码习惯
1、函数的编写
· 统一-统一输入输出格式
· 异常-考虑失败和异常情况
· 简洁-避免与业务无关的参数
· 必要-返回应该返回的参数
2、面向接口开发
· 任何一个功能,设计好架构,我们会有马上写功能的冲动,但其实第一个写的应该是接口,根据接口再去写业务,写页面,写数据层。
· 在接口中,会倒逼我们先把对象、函数,参数,返回值,调用关系都想明白了,实际是在做细节设计。
· 面向接口开发,容易实现团队协作。
· 面向接口开发,容易做自动化测试(比如对View接口测试)。
3、类依赖关系主要通过传参来体现
· 多用聚合,少用继承
· 如果一个类需要依赖另外一个类,最好把依赖类作为参数传进来。
· 这样有助于控制依赖类的数量,避免类结构复杂化。
· 这样有助于自动化测试,你可以mock依赖类的实例作为参数,来对这个类做自动化测试。
4、Model层的工作量其实很多
· 现在Model层越来越复杂了,要实现内存cache缓存、本地持久化数据、在线网络数据三级数据源,并做好相关逻辑。
· 好处是明显的:Model层可以全局复用避免了重复代码;数据效率变高了;逻辑层变简单了。
· 心得:可以理解为逻辑层的部分工作挪到Model层了,事实上,我们在刚开始写的时候,很容易把一些Model层的功能写到逻辑层。
· 经验:配合单元测试和自动化测试来写,能帮我们认清楚Model层的职责。
5、业务层(如Presenter层)要避免callback hell
· 异步回调如果在逻辑层泛滥,很容易遇到回调地狱,因为业务逻辑如果要考虑各种异步行为,复杂程度会呈指数级增长,最终逻辑失控。
· 推荐做法是在Model层处理所有callback,presenter层只保留调用model的那一层callback。
6、View层要警惕逻辑扩张
· View层只做对界面的控制,不做任何逻辑,逻辑都要放到presenter层。
· 这样有利于把Presenter复用给多个view。
· 这样有利于对UI做自动化测试。
· Adapter算View层,不算Presenter层,但Adapter应允许复用。
7、MVP和自动化测试是相辅相成的
· MVP写的规范,才好做自动化测试,如果划分的不对,自动化测试会感觉寸步难行。
· 有自动化测试为基础,可以反过来监督MVP的规范性,如果Presenter层的逻辑写到View层,会发现在View层无法对这个功能做自动化测试。
8、单元测试是代码质量的保证
· 函数名的命名规则:目标+条件+结果。
· 单元测试可以提醒我们注意处理边界数据、错误数据、无效数据、空数据等异常情况
· 在添加新功能时,单元测试快速做全面的回归测试。
· 在理想场景下,团队成员的代码提交会触发全面的自动化单元测试(这需要更高的自动化测试水平)。
9、异常处理的时机选择
· 不是所有的异常都要立即catch处理,很多时候需要throw到外层去处理。
· 例如当数据层出现问题时,应该throw给逻辑层,由逻辑层判断是否需要报错,如果数据层自己catch处理了,用户永远没有机会处理错误。
· java异常分为check异常和uncheck异常,其中uncheck异常虽然系统不建议捕获,但是我们可以视自身需要去捕获处理,比如运行环境缺少jar包,我们其实是应该捕获Error的。
关于团队协作规范
1、制定代码框架,制定项目组的开发规范,把代码量减下去,把复用量提上来。
2、架构、流程必须有文档,可以补,但不能少,建议先画图:
画图有助于提前发现问题,一般来说画不出图就是没想明白。而且人是视觉动物,语言和文字的都不如图来的直观,在图中容易发现问题。
3、接口先行,利用接口把详细设计想好,然后再分模块去写功能:
在写接口的时候,把函数和调用关系其实就设计好了,而且这时候发现问题,也就是改个函数名、参数和返回值的问题,改动成本最小。
4、函数必须要写注释,一些关键步骤也要写注释。
函数注释有利于代码可读性,为以后的可维护性打好基础。
而且,注释可以提醒我们函数的职责,避免出现过于复杂的超长函数,如果函数超长超复杂,一般就需要拆分修改了。
5、全面自动化测试付出的成本可能较高,但至少要做到对逻辑类做单元测试:
可以提高开发效率,因为测试逻辑类的话,用单元测试比手工启动App测试要快很多倍,而且什么场景都能测试。
而且逻辑类就应该是纯抽象的,如果一个逻辑类做不了单元测试,说明它职责越界了,需要修改。
同时,逻辑类是最容易让人惮于修改的,因为不知道会不会改出其他问题,覆盖了单元测试,以后再修改起来,会让人更放心一点。
主动解决问题
1、有一点前瞻性
写代码,除了实现功能之外,就是排查bug和扩展逻辑,后两者其实会占用大部分工作量。
所以,我们在写代码时,要注意方便未来对运行状态的监管和统计,也就是方便定位问题(找bug)和扩展逻辑(改代码)。
2、积极参与业务
不管产品和设计怎么样,程序员是真正实现业务的那个人,我们是必须先深刻理解业务,才能准备写出业务,所以程序员要积极参与业务。
而且,实践中,大部分错误是设计错误,参与业务也有利于避免别人给自己挖坑。
3、关于设计模式
广泛流传的23种设计模式,各有各自的优点,也各有各自的缺点,我们既要利用精妙的设计模式优化结构,又要避免过度设计增加复杂度和工作量。
管理我们的代码工程,就像管理城市一样,不可能一步到位,也不能预知未来,我们要做的就是按需成长,适时扩展。