谷歌SRE那本书中所讲到一点,就是搞业务运维或说SRE,最头疼的就是工作量随着服务规模的增长线性增加。其实个人觉得这一点放到开发中也是一样的,随着需求的增加,services、views目录下的文件越来越多,编写它们的时候都是copy&paste,维护它们的时候也是一样的任务量复制。
就其根源,个人觉得就是我们所谓“开发”对工程规范的漠视,导致维护过程中问题的累积。这里也记录一点过去积累的好的编码习惯(针对golang而言)
1,创建一个较为复杂的对象时,把New函数参数可选
比如说
type MyOperation struct {
keyone string
valone int
someConfig bool
someConfig2 bool
storage *db.Connection
}
type Opt interface {
apply(*MyOperation)
}
type optFunc func(o *MyOperation)
func (f optFunc) apply(o *MyOperation) {
f(o)
}
func WithStorage(src *db.Connection) Opt {
return optFunc(func(o *MyOperation) {
o.storage = src
}
}
func WithConfig(conf bool) Opt {
...
}
func NewOperation(mustKey string, ... Opt) (*MyOperation, error) {
op := &MyOperation {
keyone : mustKey,
}
for _, optFunc := range Opt {
optFunc(op)
}
return op, nil
}
我刚开始的时候很不理解,把一个NewOperation写这么有什么好处。但是后来发现,代码结构、可读性是真的非常重要。特别运维开发这块,国内现在就是一个起步过程,运维开发存在很多任务都是对之前代码的重构与功能维护。
我相信干过一段时间你就知道阅读别人代码的痛苦吧,可能搞懂逻辑就要花好几天,但是写代码不过一两天、两三天而已。
2,多写注释,如果一个函数参数很多,甚至可以给参数加注释,特别是我们一个操作对象,可能有n多个配置,如
func someOperation(true, true, false, false, true,...)
并且这个函数可能会在一个代码文件中出现多次,可能每次这些布尔配置参数还不一样,所以有必要加一点说明
func someOperation(true /* 允许重试/, true, false, false / 不记失败日志等*/,...)
3,减少作用域
... 上文中已经存在err 错误对象, 这个err可能并不希望被覆盖掉
if f, err := someOpt(); err != nil {
return err
}
f.xxx()
4, 尽可能避免 if 嵌套 if
多用用switch case,或者优化下逻辑,先判断异常等
有疑问加站长微信联系(非本文作者)