[Patrón de diseño de Golang] 5. Patrón prototipo

5. Modo prototipo

Modo de prototipo, utilizando instancias de prototipo para especificar los tipos de objetos creados, y crear nuevos objetos copiando estos objetos prototipo.

Por ejemplo, hay un currículum vitae, en el que la parte de información personal debe ser la misma, para que podamos usar esto como un prototipo, y luego generar una nueva instancia a través del método prototipo Clone (), modificar la información única en la nueva instancia para lograr nuestro Propósito Además, la modificación de diferentes ejemplos no debería interferir entre sí . Las operaciones específicas son las siguientes:

prototype\Cree un nuevo archivo debajo de la ruta prototype.goy el nombre del paquete es prototype:

package prototype

// ...

Se espera que el currículum contenga información como nombre, género, escuela, compañía solicitante, postulaciones para puestos, etc. Aquí usamos una estructura para almacenar información escolar:

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

Usamos el método prototipo Clone () para copiar una nueva instancia, por lo que para que las diferentes instancias no interfieran entre sí, debemos usar una copia profunda. School también necesita implementar el método Clone (), por lo que el prototipo es School () Al clonar, se llama al método Clone () de la escuela.

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

Luego está la estructura Resume y el nuevo método de instancia Resume correspondiente:

Cabe señalar aquí que la estructura en Go es un tipo de valor en lugar de un tipo de puntero. Al crear una nueva estructura compuesta, el valor de la estructura se copiará en el pasado, por lo que los punteros de la escuela se utilizan aquí. Además, se puede guardar una cierta cantidad de espacio.

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

Lo que hay que tener en cuenta sobre el método prototipo Clone () es que necesitamos usarlo r.School.Clone()para copiar r.School(en realidad un puntero) y ponerlo.

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

prototypeCree un nuevo main.gométodo de prueba en el mismo directorio de la ruta :

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

La salida es

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

Se puede ver que los cambios en School.Level en CV2 no afectaron CV1.

Además, puede cambiar el del r.Clone()medio r.School.Clone()para r.Schoolver si tiene algún efecto.

Además, puesto que la estructura en sí es el valor de tipo Go, la Resumeestructura se *Schoolcambió School, si no se utiliza r.School.Clone(), aún la interferencia entre diferentes instancias.

Ejemplo completo

Supongo que te gusta

Origin www.cnblogs.com/loveshes/p/12756323.html
Recomendado
Clasificación