[Golang design pattern] 5. Prototype pattern

5. Prototype mode

Prototype mode, using prototype instances to specify the types of objects created, and create new objects by copying these prototype objects.

For example, there is a resume, in which the personal information part should be the same, so we can use this as a prototype, and then generate a new instance through the prototype Clone () method, modify the unique information in the new instance to achieve our purpose. In addition, the modification of different examples should not interfere with each other . The specific operations are as follows:

prototype\Create a new file under the path , prototype.goand the package name is prototype:

package prototype

// ...

The resume is expected to contain information such as name, gender, school, applying company, applying for positions, etc. Here we use a structure to store school information:

type School struct {
	Name    string
	Address string
	Level   string
}

// 创建School实例,返回对应指针
func NewSchool(name, address, level string) *School {
	return &School{
		Name:    name,
		Address: address,
		Level:   level,
	}
}

We use the prototype Clone () method to copy a new instance, so in order for different instances to not interfere with each other, we should use deep copy. School also needs to implement the Clone () method, so the prototype is to School () When cloning, the School's Clone () method is called.

// School也要实现Clone()方法
func (s *School) Clone() *School {
	return NewSchool(s.Name, s.Address, s.Level)
}

// 重写School的String()方法,便于输出信息
func (s *School) String() string {
	return "{" + s.Name + " " + s.Address + " " + s.Level + "}"
}

Then there is the Resume structure and the corresponding new Resume instance method:

It should be noted here that the structure in Go is a value type rather than a pointer type. When creating a new composite structure, the value of the structure will be copied in the past, so School pointers are used here. In addition, a certain amount of space can be saved.

type Resume struct {
	Name   string
	Gender string
	// 由于Go中结构体是值类型而不是指针类型,创建新的复合结构体时,会把值复制一份过去,所以这里使用School指针
	School        *School
	Apply4Company string
	Apply4Job     string
}

func NewResume(name, gender string, school *School, company, job string) *Resume {
	return &Resume{
		Name:          name,
		Gender:        gender,
		School:        school,
		Apply4Company: company,
		Apply4Job:     job,
	}
}

The thing to note about the prototype Clone () method is that we need to use it r.School.Clone()to copy r.School(actually a pointer) and put it in.

// 原型的Clone()方法
func (r *Resume) Clone() *Resume {
	// 注意这里的r.School.Clone()
	return NewResume(r.Name, r.Gender, r.School.Clone(), r.Apply4Company, r.Apply4Job)
}

prototypeCreate a new main.gotest method in the same directory of the path :

package main

import (
	"fmt"
	"github.com/loveshes/go-design-patterns/pattern/prototype-pattern/prototype"
)

func main() {
	ncu := prototype.NewSchool("南昌大学", "江西省南昌市", "211")
	proto := prototype.NewResume("王英俊", "男", ncu, "", "")

	// 简历一
	alibaba := proto.Clone()
	alibaba.Apply4Company = "Alibaba"
	alibaba.Apply4Job = "Java Web"
	fmt.Println("alibaba:", *alibaba)

	// 简历二
	bytedance := proto.Clone()
	// 修改复合结构体中的School.Level字段,看alibaba中的是否也会改变
	bytedance.School.Level = "双一流"
	bytedance.Apply4Company = "ByteDance"
	bytedance.Apply4Job = "Go"
	fmt.Println("修改School.Level后,alibaba:", *alibaba)
	fmt.Println("修改School.Level后,bytedance:", *bytedance)
}

The output is

alibaba: {王英俊 男 {南昌大学 江西省南昌市 211} Alibaba Java Web}
修改School.Level后,alibaba: {王英俊 男 {南昌大学 江西省南昌市 211} Alibaba Java Web}
修改School.Level后,bytedance: {王英俊 男 {南昌大学 江西省南昌市 双一流} ByteDance Go}

It can be seen that the changes to School.Level in CV2 did not affect CV1.

In addition, you can change the r.Clone()middle one r.School.Clone()to r.Schoolsee if it has any effect.

Further, since the structure itself is the value Go type, the Resumestructure is *Schoolchanged School, if not used r.School.Clone(), still interference between different instances.

Complete example

Guess you like

Origin www.cnblogs.com/loveshes/p/12756323.html