原始模型模式(Prototype)
1.意图
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
2.适用性
当一个系统应该独立于它的产品创建、构成和表示时,要使用Prototype模式;以及
- 当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者
- 为了避免创建一个与产品类层次平行的工厂类层次时;或者
- 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
3.结构
4.代码
package prototype
/*
# 原型模式
原型模式使用原型实例指定创建对象的种类,并且通过拷贝原型对象创建新的对象。
原型模式使对象能复制自身,并且暴露到接口中,使客户端面向
接口编程时,不知道接口实际对象的情况下生成新的对象。
原型模式配合原型管理器使用,使得客户端在不知道具体类的情况下,
通过接口管理器得到新的实例,并且包含部分预设定配置。
*/
import (
"testing"
"unsafe"
)
//Cloneable 是原型对象需要实现的接口
type Cloneable interface {
Clone() Cloneable
}
type PrototypeManager struct {
prototypes map[string]Cloneable
}
func NewPrototypeManager() *PrototypeManager {
return &PrototypeManager{
prototypes: make(map[string]Cloneable),
}
}
func (p *PrototypeManager) Get(name string) Cloneable {
if v,ok:=p.prototypes[name];ok{
return v
}
return nil
}
func (p *PrototypeManager) Set(name string, prototype Cloneable) {
p.prototypes[name] = prototype
}
var manager *PrototypeManager
func (this *Sheep) Clone() Cloneable {
sheep := *this
return &sheep
}
type Sheep struct {
name string
}
func init() {
manager = NewPrototypeManager()
s := &Sheep{
name: "多利",
}
d := &Dog{
name: "旺财",
}
manager.Set("多利", s)
manager.Set("旺财", d)
}
type Dog struct {
name string
}
func (this *Dog) Clone() Cloneable {
dog := *this
return &dog
}
func TestClone(t *testing.T) {
t1 := manager.Get("旺财")
t2 := t1.Clone()
t.Log(t2)
t.Log(t1==t2)
}
func TestCloneFromManager(t *testing.T) {
sheep := manager.Get("多利").Clone().(*Sheep)
t.Log(&sheep)
duo := manager.Get("多利")
t.Log(&duo)
t.Log(manager.Get("多利")==sheep)
}
//浅拷贝: 指拷贝对象时仅仅拷贝对象本身
//(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
//深拷贝 :深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
//用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
//原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建
//另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:
//通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象
//通过请求原型对象拷贝它们自己来实施创建
func TestFullClone(t *testing.T){
type Tools struct {
tool string
}
type Person struct {
name string
age int
tools Tools
}
p1:=&Person{"张三",30,Tools{"钳子"}}
p2:=p1
t.Log(unsafe.Sizeof(p2.name))
}