为什么要降低代码复杂度
好的项目都是迭代出来的,所以代码肯定是会被人维护的
降低代码复杂度就是为了降低下一个维护人的维护成本,更简单地理解跟修改代码
代码组成
代码逻辑 = 控制逻辑 + 业务逻辑
控制逻辑 = 控制业务逻辑的代码
例如:加缓存,开并发,异步 …
业务逻辑 = 真正业务的代码
例如:调下游接口,查询数据库 …
控制逻辑 与 业务逻辑分离
一般情况下,后续的维护只需关注 业务逻辑 代码
因此将 控制逻辑 与 业务逻辑 分离就能降低维护成本
- 易懂
分离后业务的代码就少了,少了就更简单,也更聚焦了,后续维护的人只需关注业务逻辑的方法即可- 减少出错
控制逻辑很多情况下都差不多,越写会越熟练,甚至可以抽成公共方法,提升效率又减少出错
例子
缓存逻辑 与 查询逻辑 分离
DoSomethingCache 方法是 缓存控制逻辑
doSomething 方法是 业务逻辑
下一个维护的人只需要关注 doSomething 方法,维护成本低
后续有其他缓存业务时可以 copy DoSomethingCache 方法,不容易出错(也可以封装成公共方法)
并发逻辑 与 查询逻辑 分离
DoSomethingMulit 方法是 并发控制逻辑
doSomething 方法是 业务逻辑
下一个维护的人只需要关注 doSomething 方法,维护成本低
后续有其他并发业务时可以 copy DoSomethingMulit 方法,不容易出错(也可以封装成公共方法)
代码
缓存逻辑 与 查询逻辑 分离
// 公有的带缓存的方法
func DoSomethingCache() (string, error) {
// 从缓存取
cacheKey := "XXX"
redisRes, err := redishelper.GetKey(cacheKey)
if err == nil {
return redisRes, nil
}
// 实时计算
res, err := doSomething() // 业务逻辑
if err != nil {
return res, err
}
// 存入缓存
redishelper.SetKey(cacheKey, 10*60, res)
return res, nil
}
// 私有的业务逻辑方法
func doSomething() (string, error) {
// ...
return "业务逻辑", nil
}
并发逻辑 与 查询逻辑 分离
// 公有的并发的方法
func DoSomethingMulit(list []string) ([]string, error) {
var (
res = []string{}
err error
wg sync.WaitGroup
lock sync.Mutex
limitChan = make(chan struct{}, 4)
)
// 并发
for _, v := range list {
wg.Add(1)
limitChan <- struct{}{}
go func(str string) {
defer exception.RecoverPanic()
defer wg.Done()
defer func() {
<-limitChan
}()
tmpRes, tmpErr := doSomething(str) // 业务逻辑
if err != nil {
fmt.Println("err:", err)
return
}
lock.Lock()
defer lock.Unlock()
if tmpErr != nil {
err = tmpErr
}
res = append(res, tmpRes)
}(v)
}
wg.Wait()
if err != nil {
return res, err
}
return res, nil
}
// 私有的业务逻辑方法
func doSomething(str string) (string, error) {
// HTTP调用大数据接口...
return "业务逻辑", nil
}