golang设计模式---原型模式

场景

当对象的创建成本比较大,并且同一个类的不同对象间差别不大时(大部分属性值相同),如果对象的属性值需要经过复杂的计算、排序,或者需要从网络、DB等这些慢IO中获取、亦或者或者属性值拥有很深的层级,这时就是原型模式发挥作用的地方了。

深拷贝,浅拷贝

// Keyword 搜索关键字
type Keyword struct {
 word      string
 visit     int
 UpdatedAt *time.Time
}

// Clone 这里使用序列化与反序列化的方式深拷贝
func (k *Keyword) Clone() *Keyword {
 var newKeyword Keyword
 b, _ := json.Marshal(k)
 json.Unmarshal(b, &newKeyword)
 return &newKeyword
}

// Keywords 关键字 map
type Keywords map[string]*Keyword

// Clone 复制一个新的 keywords
// updatedWords: 需要更新的关键词列表,由于从数据库中获取数据常常是数组的方式
func (words Keywords) Clone(updatedWords []*Keyword) Keywords {
 newKeywords := Keywords{}

 for k, v := range words {
  // 这里是浅拷贝,直接拷贝了地址
  newKeywords[k] = v
 }

 // 替换掉需要更新的字段,这里用的是深拷贝
 for _, word := range updatedWords {
  newKeywords[word.word] = word.Clone()
 }

 return newKeywords
}

原型模式的优点

  • 某些时候克隆比直接new一个对象再逐属性赋值的过程更简洁高效,比如创建层级很深的对象的时候,克隆比直接用构造会方便很多。
  • 可以使用深克隆方式保存对象的状态,可辅助实现撤销操作。

原型模式的缺点

  • clone方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
  • 当实现深克隆时,需要编写较为复杂的代码,尤其当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆。因此,深克隆、浅克隆需要运用得当。

参考资料

卡尔文_ 网管叨bi叨

你可能感兴趣的:(Golang,golang,设计模式,原型模式)