【Go-设计模式】原型模式 详解

原型模式:
概念:
用 原型实例 指定 创建对象的 种类,并且通过 拷贝这些原型,创建新的对象
原型模式是一种 创建型设计模式,允许 一个对象再创建另外一个可定制的对象,无需知道 如何创建的细节
工作原理是:通过将一个 原型对象 传给那个要发动创建的对象,这个 要发动创建的对象 通过 请求原型对象拷贝它们自己 来实施创建
原型模式配合 原型管理器 使用,使得客户端在 不知道具体类 的情况下,
通过接口管理器得到 新的实例,并且包含 部分预设定配置

UML:

- Prototype:
原型管理器,管理 原型对象 的 生成 与 注册 - ConcretePrototype:
具体的原型类, 实现一个 克隆自己 的操作 - Client:
让一个 原型对象 克隆自己,从而 创建一个新的对象(属性一样)
示例:
Cloneable接口 · 手动实现
type Cloneable interface {、
Clone() Cloneable
}
原型管理器
type PrototypeManager struct {
prototypes map[string]Cloneable
}
func NewPrototypeManager() *PrototypeManager {
return &PrototypeManager{
prototypes: make(map[string]Cloneable),
}
}
func (this PrototypeManager) Get(name string) Cloneable {
return this.prototypes[name]
}
func (this *PrototypeManager) Set(name string, obj Cloneable) {
this.prototypes[name] = obj
}
被克隆的类型
type TestModel1 struct {
Attribute1 int64
}
type TestModel2 struct {
Attribute2 string
Attribute3 TestModel1
}
func (this TestModel2) Clone() base23.Cloneable {
newModel := this
return newModel
}
测试
package main
import (
"DemoProject/design/base23" // 根据自己的项目路径定制
"fmt"
)
var manager base23.PrototypeManager
var model TestModel2
func init() {
manager := base23.NewPrototypeManager()
model := TestModel2{
Attribute2: "youzg",
Attribute3: TestModel1{
Attribute1: 666,
},
}
manager.Set("TestModel2", model)
model.Attribute2 = "YOUZG" // 改变 原对象 的值
}
func main() {
// clone
cloneModel1 := manager.Get("TestModel2")
// model: {YOUZG {666}}, cloneModel1: {youzg {666}}, model is cloneModel1 : [false]
fmt.Printf("model: %v, cloneModel1: %v, model is cloneModel1 : [%v]\n", model, cloneModel1, model == cloneModel1)
fmt.Println("===============================================================================")
cloneModel2 := manager.Get("TestModel2").Clone()
// model: {YOUZG {666}}, cloneModel2: {youzg {666}}, model is cloneModel2 : [false]
fmt.Printf("model: %v, cloneModel2: %v, model is cloneModel2 : [%v]\n", model, cloneModel2, model == cloneModel2)
fmt.Println("===============================================================================")
cloneModel11 := cloneModel1.(TestModel2)
cloneModel11.Attribute3.Attribute1 = 999
// cloneModel11: {youzg {999}}, cloneModel2: {youzg {666}}, cloneModel11 is cloneModel2 : [false]
fmt.Printf("cloneModel11: %v, cloneModel2: %v, cloneModel11 is cloneModel2 : [%v]\n", cloneModel11, cloneModel2, cloneModel11 == cloneModel2)
// manager.Get == model.Clone(): false
fmt.Printf("manager == model.Clone(): %v", cloneModel1 == model.Clone())
}
注意事项
- 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率
- 不用重新初始化对象,而是 动态地获得对象运行时的状态
- 如果 原始对象 发生变化(增加或者减少属性),其它克隆对象 的也会发生相应的变化,无需修改代码
(注意:此处的更改,是指 对象的结构 发生变化,并不是指 对象的属性值 发生变化,
被克隆的对象 和 原对象之间,属性值做修改不会影响对方) - 在实现 深克隆 的时候可能需要比较复杂的代码

浙公网安备 33010602011771号