[Шаблон дизайна Golang] 5. Шаблон прототипа

5. Режим прототипа

Режим прототипа, использующий экземпляры прототипа для указания типов создаваемых объектов и создания новых объектов путем копирования этих объектов-прототипов.

Например, есть резюме, в котором часть личной информации должна быть одинаковой, поэтому мы можем использовать ее в качестве прототипа, а затем сгенерировать новый экземпляр с помощью метода Clone () прототипа, изменить уникальную информацию в новом экземпляре для достижения нашего цель. Кроме того, модификации разных примеров не должны мешать друг другу . Конкретные операции заключаются в следующем:

prototype\Создайте новый файл под путем , prototype.goи имя пакета prototype:

package prototype

// ...

Предполагается, что резюме будет содержать такую ​​информацию, как имя, пол, школа, компания, подающая заявку, заявление о приеме на работу и т. Д. Здесь мы используем структуру для хранения информации о школе:

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

Мы используем прототипный метод Clone () для копирования нового экземпляра, поэтому, чтобы разные экземпляры не мешали друг другу, мы должны использовать глубокое копирование. School также необходимо реализовать метод Clone (), поэтому прототип предназначен для School () При клонировании вызывается школьный метод Clone ().

// 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 + "}"
}

Затем есть структура Resume и соответствующий новый метод экземпляра Resume:

Здесь следует отметить, что структура в Go является типом значения, а не типом указателя.При создании новой составной структуры значение структуры будет скопировано в прошлом, поэтому здесь используются указатели School. Кроме того, можно сэкономить определенное количество места.

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

В отношении прототипа метода Clone () следует отметить, что нам нужно использовать его r.School.Clone()для копирования r.School(фактически указатель) и вставки в него.

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

prototypeСоздайте новый main.goметод тестирования в том же каталоге пути :

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

Выход

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

Видно, что изменения в School.Level в CV2 не повлияли на CV1.

Кроме того, вы можете изменить r.Clone()средний, r.School.Clone()чтобы r.Schoolувидеть, имеет ли он какой-либо эффект.

Кроме того, так как сама структура является значение типа Go, то Resumeструктура *Schoolизменилась School, если не используется r.School.Clone(), по- прежнему помех между различными экземплярами.

Полный пример

рекомендация

отwww.cnblogs.com/loveshes/p/12756323.html
рекомендация