编程笔记


1. 数据结构

1.1 结构拆分

1.1.1 数据层级原则上不宜过深

  • 为了方便阅读代码,且保证在查找相关数据结构时,能较快跳转到所定义的文件中,从而进行扩展或修改等操作。
  • 同一个文件进行查找或跳转,在一定程度上,会比在多个文件中进行查找跳转更优。

1.1.2 多层基本数据组合而成的数据需要进行合理拆分

  • 当存在多层基本数据组合而成的数据时,为了方便理解,需要进行合理拆分及添加相应注释。
struct Data {
  groupListMap map[int][][]int
}

// 进行简单拆分
type group []int // 单个组合
type groupList []group // 组合列表
struct Data {
  groupListMap map[int]groupList
}

1.2 数据状态

1.2.1 标记or状态值

  • 当存在多种标记时,则要考虑是否可以通过状态值来达到多种标记的作用,以减少多种标记字段的维护和提高使用的方便性。

2. 协议相关

2.1 协议设计

2.1.1 功能的统一

  • 设计协议时,不代表功能拆分得越细,越容易理解和使用。而是应该将请求和反馈协议,进行配套,避免出现单个请求,而又多种反馈协议的出现,否则会导致理解和使用变得麻烦。

2.1.2 尽量使用向后添加字段来扩展协议

  • 在协议的使用上,为了方便理解和使用,而应该尽量使用向后添加字段的方式来扩展协议,不宜通过json字符串将数据保存到一个string类型的字段。

2.2 协议命名

2.2.1 适当使用缩写

  • 由于可使用注释,故而在设计协议及其字段时,要保证既能保证命名简单,又能反映出大概用途,则可适当地利用缩写来实现。
  • 需要注意的是,单词缩写往往不是简单地截取前几个字母,而应该优先查字典,字典中实在没有的话,则得尽量体现出原有的意思。

3. 代码设计

3.1 优雅设计

  • 封装,尽可能掩盖模块内部实现细节,方便进行迭代和替换
  • 继承,遵循LSP,非 is-a 或 is-a-kind-of 的关系,而是 hehaves-like-a, is-substitutable-for 的关系
  • SRP,一个模块只负责一类事情,有且只有一个被修改的理由
  • DIP,高层策略性代码不要依赖实现底层细节,底层细节的代码应该依赖高层策略性代码
  • LSP,使用可替换的组件来构建软件系统,同一层次的组件遵守同一个行为约定,以方便替换
  • SRP,不要依赖其不直接使用的组件OCP,通过新增代码修改系统行为,而非修改原来的代码

重点:

  • 模块一定要隐藏实现细节,只暴露必要接口
  • 优先考虑组合,后考虑在行为一致的基础上使用继承
  • 高层策略性代码不要依赖实现底层细节,底层细节的代码应该依赖高层策略性代码

3.2 代码层级

  • 在使用判断逻辑时,尽量通过使用return、continue或break,来避免代码层级过深二导致阅读困难。
func traversing(v, vals) bool {
  if v != nil {
    for _,val := range vals {
      if val == v {
        return true
      }
    }
  }
  return false
}

// 可修改为以下方式
func traversing(v, vals) bool {
  if v != nil {
    return false
  }
  for _,val := range vals {
    if val == v {
      return true
    }
  }
  return false
}

results matching ""

    No results matching ""