我们今天聊一聊研发的依赖问题。
一个App就是一堆git仓库+一堆逻辑的组合,就构成了完整的业务逻辑。
衡量模块划分的标准其实就是 “沟通量”。
换个词语:职责划分、代码边界。
常用的划分是功能划分
通过引入各种仓库,给我们的研发带来了边界
api 'jp.wasabeef:glide-transformations:4.0.1'
api "com.github.bumptech.glide:glide:${glide_version}"
//黄油刀
annotationProcessor "com.jakewharton:butterknife-compiler:$rootProject.butterknifeVersion"
api "com.jakewharton:butterknife:$rootProject.butterknifeVersion"
第三方库会明确的程序提供了什么功能,有个主入口。尽量将逻辑都包裹在内部。其主要的设计理念:职责明确出来。
通过编写一堆的interface来定义代码的能力。
这也引出了我们沟通的第一个问题:数据依赖
为了规矩数据依赖,接口定义需要充分考量。
如何定义接口定义是否合理?入参有哪些?
核心
涉及到3个指标
- 指标1:参数的必要性与和合理性
- 指标2:接口变动频率
- 指标3:接口的重合度
指标1:参数的必要性与合理性
fun navigate(name:String?, classId:Int, studentId:Int) {}
单从这里看,无法区分参数的必要性。
必要,即调用方都会使用到的。
若超过一定比例的调用方都传递这个参数,可以判定为有必要的。
比例的数值可以是90%
那剩下的10%,就属于小众场景。
我们就有必要考量下,是否这个参数可以通过其他方式取代。
每一个额外参数都会增加 使用者的 负担,这必然带来额外的学习和维护成本。
指标2:接口变动频率
MVP、MVVM这两种模式,就是典型的案例。若活动页面经常变化,用我们可以用MVVM,其优势在于改变UI不需要调整逻辑。换言之,就是interface没有变化。那么,页面变化,就不会增加很多的沟通成本。不需要跟其他端的同事对接。
我们应该尽量的减少接口的改动,而只是调整实现,这样才能减少跨端、跨库的沟通成本。
无论英雄技能怎么变,接口不变,其实也就只是增加个技能。这仍然是理想的情况。
研发人员之间,应尽量减少沟通次数,提升沟通质量。
更多的,是要关注业务逻辑是否分割的恰当?业务边界是否清晰?
不断的审查我们的拆分决策。适时地调整。以匹配我们的业务形态。
注意:业务是不能预测的,是有破坏性的。作为研发人员只能是去做适配。
接口变动/接口实现,其值越小,说明interface定义就越合理。
实际开发中,将git提交commit次数作为一次变更。
git的提交次数越少,自然是越好的。频繁的变更会带来文件变化的波动。
业务逻辑的拆分粒度以 当前团队的 可支持的并发数 作为依据。
一个端有 10个人研发 跟一个端 仅2个人研发,其粒度差异是相当大的。
设计原则:SOLID中提及的 Single Responsibility Principle(单一职责原则),我们要把注意力放在静态的结构上。
interface的实现类,经历了多次变更,但interface类却并未变化?
这个接口的稳定性就非常好。
指标3:接口的重合度。是否过度设计?过度抽象?
首先,我们意识到一个问题:是否所有一样的功能,就要抽象出来做封装?
然后,所有调用的地方必须要使用这个功能。
这仅仅是为了保证 实现的一致性。
这种组合关系,能否通过,累加几个功能 实现呢?
这就是做加法还是做乘法的选择?
我们的出发点是 需求的内在统一,然后将实现整理成一份。
这里有严格先后顺序,先有需求的统一,再有功能的统一。
先有道,而后法,再尔术,放有器。
需求的内在统一,即是道;
是否无能为力?
我们还是会开技术研讨会,讨论新App的技术架构
这也并非是无效的。
我留意一下。
一般,会议最后,领导总是大腿一拍,我们选择了XXX,又舍弃了XXX。
我们对 取舍 达成共识的;
领导又说:后面,有变化了再说。
我们对 保持迭代更新 达成了共识。
完美~~~~~~
小结
我们很难定义如何拆分模块?无法做提前预测,有没办法一次到位。
这意味着,要坚持 日常反思。
我们是否有拆分不合理的地方?在哪些方面不合理?是否有更加的恰当方案?并记录在日志上,得空就看看,在业务迭代周期中,排上议程。