业务逻辑与控制代码分离实践

写代码时,控制逻辑的代码往往与业务逻辑混在一起,控制部分的代码很难被复用。

实现功能:从一个channel中批量读取数据,积攒够了50条数据,使用transaction将数据保存到数据库,减少对数据库的访问次数。

实现如下:

func (m *FaceEnroll) createTasks(files <-chan string, tasks chan<- *taskModels.Task) {
   batchCount := 50
   count := 0
   var batchTasks []*taskModels.Task
   for {
      select {
      case file, ok := <-files:
         if !ok {
            m.SaveTasks(&batchTasks, tasks)
            return
         }
         task := createTaskData(file, m.ID)
         batchTasks = append(batchTasks, task)
         count++
         if count == batchCount {
            m.SaveTasks(&batchTasks, tasks)
            count = 0
         }
      default:
         m.SaveTasks(&batchTasks, tasks)
         time.Sleep(time.Millisecond * 10)
      }
   }
}

问题:SaveTasks、createTaskData等业务代码与控制代码混在一起,另一个地方也有类似的需求,代码需要完全重新写一遍。

改进:分离控制部分的代码,如下:

func batchExecute(input <-chan interface{}, process func([]interface{})) {
   batchMaxCount := 50
   index := 0
   var batchInputs []interface{}
   for {
      select {
      case i, ok := <-input:
         if !ok {
            process(batchInputs)
            return
         }
         batchInputs = append(batchInputs, i)
         index++
         if index == batchMaxCount {
            process(batchInputs)
            index = 0
         }
      default:
         process(batchInputs)
         time.Sleep(time.Millisecond * 10)
      }
   }
}

其中,process里面是业务逻辑,batchExecute只是实现从input channel中取数据,到一定数量时,调用一次process函数。

小结:控制和业务逻辑分离,复杂度降低了,代码质量提升了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,442评论 0 9
  • 与大多数人一样,一直很普通,沿着普通的轨迹行走,研究生毕业—工作—恋爱—成家—生子,当我再次阅读《飘》这本书后,发...
    lily123321阅读 207评论 0 0
  • 大年初二,我要上班。在这之前我参加了一个心理学书籍的阅读,一共有七本。其中一本是心理学与生活,很厚的一本书。我想着...
    点心灯张权阅读 1,718评论 2 9