框架设计

在做功能开发时,其实有很多实现的方式,比如,我们可以通过 context 来传递参数,也可以通过函数参数的方式来传递。我们可以把行为抽象为单个接口, 也可以是多个组合接口。思考这些问题,有时候会让人特别苦恼。

我总结了如何克服这种纠结的方式,先完全不考虑代码的设计和质量,先把需要的功能都实现了,把基础的流程走通,代码怎么组织都不重要,哪怕都写个一个方法体里呢。 基本的功能完成之后,我们再开始做优化。优秀的代码都是不断优化重构出来的,想一下子就把类设计的特别合理是非常困难的。

对于有代码完美主义情节的人来说,怎么写代码是一件很纠结的事情,他们总是试图把代码写的一目了然。但对于没有这种情节的人来说,写代码就简单多了。 很现实的是,一般的业务环境,你代码写的好不好,跟你在团队的发展其实没有什么关系。你的成绩取决于为业务带来了什么收益,代码只是工具,万不可本末倒置。

代码的可读性

不要有巨长的方法体,以及基本规范的命名是最基本的。我见过太多巨长的方法体,各种条件判断,一层if嵌套一层if,这样的代码除了无力感就剩下无力感了。

类的层次结构,类之间的依赖关系也要尽量简单,职责上要做到单一,所有的类设计要尽量满足高内聚低耦合的特征。

代码的扩展性

扩展的根本问题在于:基于抽象而不是具体,基于接口编程而不是具体的实现类。多为今后的扩展考虑,当扩展新的功能时,不需要推倒重来。通过修改已有的老逻辑来扩展功能, 这种方式很容易影响到之前的逻辑。最佳的方案就是,每次的功能扩展,只需要在现有的基础上追加新的代码,之前的老逻辑不需要改动。

扩展新功能涉及到修改老代码,非常容易出错的一件事。代码逻辑上,新开发的逻辑要和老逻辑做隔离,即使新开发的逻辑出错了,最好也不要影响到老的逻辑。 每次扩展新的代码,我都习惯增加代码,而不是在原有代码的基础上做改动

每个实现类都抽象一个接口实现,可能存在一种情况,每个接口都只有一个实现类。Go 中这也是比较痛的一个问题,因为通过接口编程的方式,在代码的调用链查找上并不直观, 这也是需要我们仔细考虑的

代码的性能

代码的性能特别考验开发者的设计水平,如果你的代码实现简单,但是性能差的一匹,那别人肯定不会用。

比如限流的框架,会对每个请求进行一次处理,内部使用 map 结构的话,就涉及到加写锁,而加写锁相当于所有的请求都串行执行,可能也没什么问题,但性能的点必须考虑到。

代码的容错性

即使框架代码出了问题,它的影响范围非常有限,可能只是一个简单的功能缺失,而不会导致系统功能宕掉。当然,这和使用者的用法有很大关系,在设计系统的时候, 我们就要尽力做好容错,或者说,提供更多的可选择性。