golang 原型模式与原型模式的扩展

一、定义

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。

二、最简单的原型模式

原型模式即通过复制原型对象创建一个和原型相同的或相似的对象,因此,我们可以给类(struct)增加一个方法,Clone()来返回对象的复制品即可,代码如下:可以看到通过调用Clone生成了一个和原来一样的一个对象。

func main1() {
	person1 := new(Person)
	person1.Age = 12
	person1.Nation = "China"
	person1.Name="test"

	//通过原型去创建
	person2 := person1.Clone()
	fmt.Println(person2.Name)
}

type Person struct {
	Name string
	Age uint8
	Nation string
}

func (person *Person) Clone() *Person {
	newPerson := new(Person)
	newPerson.Name = person.Name
	newPerson.Age = person.Age
	newPerson.Nation = person.Nation
	return newPerson
}

三、带抽象接口的原型模式

我们知道java中有一个Cloneable接口,实现该接口,即完成了原型模式的定义。现在我们模仿java中的定义来重新完善一下我们的原型模式。代码如下:注意的是,java中的Clone返回的是最顶级的Object对象,因此我们这里返回的是interface{},在使用时,需要转换对象:即变量名.(转换的类型名称)

func main2() {
	person1 := new(Person)
	person1.Age = 12
	person1.Nation = "China"
	person1.Name="test"
	dog1 := new(Dog)
	dog1.Name = "dog1"
	dog1.Master = person1

	dog2,ok := dog1.Clone().(*Dog) //注意这里是指针,因为方法返回的是指针类型
	if !ok{
		fmt.Println("转换失败。。。。")
	}
	fmt.Println(dog2.Name)
	fmt.Println(dog2.Master.Name)
}

type Dog struct {
	Name string
	Master *Person
}

type Cloneable interface {
	Clone() interface{}
}

func (dog *Dog) Clone() interface{} {
	newDog := new(Dog)
	newDog.Name = dog.Name
	newDog.Master = dog.Master//这里用的是浅拷贝
	return newDog
}

四、带原型管理器的原型模式

通过上面的原型模式,我们已经很方便的创建对象了,但是,当我们需要创建不同类型的对象时,我们需要调用不同的对象来进行扩展,多了的情况下很不方便。
在原型模式的基础上增加了一个原型管理器 PrototypeManager 类。该类用map保存多个不同的原型,这样,我们就可以通过该管理器获取不同的类型原型。代码如下:通过传入不同的类型参数名,即可获取到不同的类型原型(cat或dog)

//带原型管理器的原型模式
func main() {
	cat1 := new(Cat)
	cat1.Name="cat1"

	dog1 := new(Dog)
	dog1.Name = "dog1"
	//设置原型管理类
	manager:= new(AnimnalProtoManager)
	manager.SetProto("cat",cat1)
	manager.SetProto("dog",dog1)

	//从原型管理类中获取所需的原型
	dog2,ok := manager.GetProto("dog").Clone().(IAnimal)
	if !ok{
		fmt.Println("转换失败")
	}
	dog2.Speak()

	cat2,ok := manager.GetProto("cat").Clone().(*Cat)
	if !ok{
		fmt.Println("转换失败")
	}
	fmt.Println(cat2.Name)
	cat2.Speak()

}

type IAnimal interface {
	Cloneable
	Speak()
}

func (dog *Dog) Speak() {
	fmt.Println("汪汪汪。。。。")
}

type Cat struct {
	Name string
	Master *Person
}

func (cat *Cat) Clone() interface{} {
	newCat := new(Cat)
	newCat.Name = cat.Name
	newCat.Master = cat.Master//这里用的是浅拷贝
	return newCat
}

func (cat *Cat) Speak() {
	fmt.Println("喵喵喵^^^^^^")
}

//可以根据传入不同的参数来生成指定的狗原型,比如,田园犬
type AnimnalProtoManager struct {
	protoMap map[string]IAnimal
}

func (manager *AnimnalProtoManager) GetProto(class string) IAnimal {
	proto,ok := manager.protoMap[class]
	if ok {
		return proto
	}
	return nil
}

func (manager *AnimnalProtoManager) SetProto(class string, proto IAnimal) {
	if manager.protoMap == nil{
		manager.protoMap = make(map[string]IAnimal)
	}
	manager.protoMap[class] = proto
}

golang 原型模式与原型模式的扩展_第1张图片

你可能感兴趣的:(golang,设计模式,golang,设计模式,接口)