mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2025-02-16 17:23:15 +03:00
finish prototype model
This commit is contained in:
parent
936f13d150
commit
e8318e8b01
@ -1,5 +1,5 @@
|
||||
# 原型模式
|
||||
|
||||
原型模式使对象能复制自身,并且暴露到接口中,使客户端面向接口编程时,不知道接口实际对象的情况下生成新的对象。
|
||||
原型模式用于快速复制具有相同属性的自身对象.
|
||||
|
||||
原型模式配合原型管理器使用,使得客户端在不知道具体类的情况下,通过接口管理器得到新的实例,并且包含部分预设定配置。
|
||||
一般是通过实现实现: `Clone()`接口来实现,注意**必须返回新的内存实例**.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user