finish prototype model

This commit is contained in:
Edward 2020-04-24 17:52:24 +08:00
parent 936f13d150
commit e8318e8b01
3 changed files with 46 additions and 38 deletions

View File

@ -1,5 +1,5 @@
# 原型模式
原型模式使对象能复制自身,并且暴露到接口中,使客户端面向接口编程时,不知道接口实际对象的情况下生成新的对象。
原型模式用于快速复制具有相同属性的自身对象.
原型模式配合原型管理器使用,使得客户端在不知道具体类的情况下,通过接口管理器得到新的实例,并且包含部分预设定配置。
一般是通过实现实现: `Clone()`接口来实现,注意**必须返回新的内存实例**.

View File

@ -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
}

View File

@ -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)
}