diff --git a/creation/07_prototype/README.md b/creation/07_prototype/README.md index 62e3ef0..c2bfbe2 100644 --- a/creation/07_prototype/README.md +++ b/creation/07_prototype/README.md @@ -1,5 +1,5 @@ # 原型模式 -原型模式使对象能复制自身,并且暴露到接口中,使客户端面向接口编程时,不知道接口实际对象的情况下生成新的对象。 +原型模式用于快速复制具有相同属性的自身对象. -原型模式配合原型管理器使用,使得客户端在不知道具体类的情况下,通过接口管理器得到新的实例,并且包含部分预设定配置。 +一般是通过实现实现: `Clone()`接口来实现,注意**必须返回新的内存实例**. diff --git a/creation/07_prototype/prototype.go b/creation/07_prototype/prototype.go index 2da0ec6..3ec7ce5 100644 --- a/creation/07_prototype/prototype.go +++ b/creation/07_prototype/prototype.go @@ -1,24 +1,26 @@ package prototype -//Cloneable 是原型对象需要实现的接口 +//Cloneable is the key interface type Cloneable interface { Clone() Cloneable } -type PrototypeManager struct { - prototypes map[string]Cloneable +//cloneLab 克隆实验室,可以克隆很多动物 +type cloneLab struct { + animals map[string]Cloneable } -func NewPrototypeManager() *PrototypeManager { - return &PrototypeManager{ - prototypes: make(map[string]Cloneable), +//new 返回一个 +func newCloneLab() *cloneLab { + return &cloneLab{ + animals: make(map[string]Cloneable), } } -func (p *PrototypeManager) Get(name string) Cloneable { - return p.prototypes[name] +func (c *cloneLab) Get(name string) Cloneable { + return c.animals[name] } -func (p *PrototypeManager) Set(name string, prototype Cloneable) { - p.prototypes[name] = prototype +func (c *cloneLab) Set(name string, newObject Cloneable) { + c.animals[name] = newObject } diff --git a/creation/07_prototype/prototype_test.go b/creation/07_prototype/prototype_test.go index cdde8f5..4b83a5d 100644 --- a/creation/07_prototype/prototype_test.go +++ b/creation/07_prototype/prototype_test.go @@ -2,51 +2,57 @@ package prototype import "testing" -var manager *PrototypeManager +//cloneLab 克隆实验室 +var lab *cloneLab -type Type1 struct { - name string +type sheep struct { + name string + weight int } -func (t *Type1) Clone() Cloneable { - tc := *t +func (s *sheep) Clone() Cloneable { + tc := *s return &tc } -type Type2 struct { - name string +type cow struct { + name string + gender bool } -func (t *Type2) Clone() Cloneable { - tc := *t - return &tc +func (c *cow) Clone() Cloneable { + newCow := &cow{ + gender: c.gender, + name: c.name, + } + return newCow } func TestClone(t *testing.T) { - t1 := manager.Get("t1") - t2 := t1.Clone() + sheep1 := &sheep{ + name: "sheep", + weight: 10, + } - if t1 == t2 { + sheep2 := sheep1.Clone() + + if sheep1 == sheep2 { t.Fatal("error! get clone not working") } } -func TestCloneFromManager(t *testing.T) { - c := manager.Get("t1").Clone() +func TestCloneFromLab(t *testing.T) { - t1 := c.(*Type1) - if t1.name != "type1" { + lab := newCloneLab() + + lab.Set("cow", &cow{name: "i am cow", gender: true}) + + c := lab.Get("cow").Clone() + + cw := c.(*cow) + if cw.name != "i am cow" { t.Fatal("error") } } - -func init() { - manager = NewPrototypeManager() - - t1 := &Type1{ - name: "type1", - } - manager.Set("t1", t1) -}