Spring SALE
Prototype

Prototype en Go

Prototype es un patrón de diseño creacional que permite la clonación de objetos, incluso los complejos, sin acoplarse a sus clases específicas.

Todas las clases prototipo deben tener una interfaz común que haga posible copiar objetos incluso si sus clases concretas son desconocidas. Los objetos prototipo pueden producir copias completas, ya que los objetos de la misma clase pueden acceder a los campos privados de los demás.

Ejemplo conceptual

Vamos a intentar imaginar el patrón Prototype utilizando un ejemplo basado en el sistema de archivos del sistema operativo. El sistema de archivos del SO es recursivo: las carpetas contienen archivos y carpetas, que también pueden incluir archivos y carpetas, y así sucesivamente.

Cada archivo y carpeta puede representarse por una interfaz inode. La interfaz inode incluye también la función clone.

Las estructuras file y folder implementan las funciones print y clone, ya que son del tipo inode. Observa también la función clone tanto en file como en folder. La función clone en ambas devuelve una copia del archivo o la carpeta respectivos. Durante la clonación, añadimos la palabra clave “_clone” para el campo del nombre.

inode.go: Interfaz prototipo

package main

type Inode interface {
	print(string)
	clone() Inode
}

file.go: Prototipo concreto

package main

import "fmt"

type File struct {
	name string
}

func (f *File) print(indentation string) {
	fmt.Println(indentation + f.name)
}

func (f *File) clone() Inode {
	return &File{name: f.name + "_clone"}
}

folder.go: Prototipo concreto

package main

import "fmt"

type Folder struct {
	children []Inode
	name     string
}

func (f *Folder) print(indentation string) {
	fmt.Println(indentation + f.name)
	for _, i := range f.children {
		i.print(indentation + indentation)
	}
}

func (f *Folder) clone() Inode {
	cloneFolder := &Folder{name: f.name + "_clone"}
	var tempChildren []Inode
	for _, i := range f.children {
		copy := i.clone()
		tempChildren = append(tempChildren, copy)
	}
	cloneFolder.children = tempChildren
	return cloneFolder
}

main.go: Código cliente

package main

import "fmt"

func main() {
	file1 := &File{name: "File1"}
	file2 := &File{name: "File2"}
	file3 := &File{name: "File3"}

	folder1 := &Folder{
		children: []Inode{file1},
		name:     "Folder1",
	}

	folder2 := &Folder{
		children: []Inode{folder1, file2, file3},
		name:     "Folder2",
	}
	fmt.Println("\nPrinting hierarchy for Folder2")
	folder2.print("  ")

	cloneFolder := folder2.clone()
	fmt.Println("\nPrinting hierarchy for clone Folder")
	cloneFolder.print("  ")
}

output.txt: Resultado de la ejecución

Printing hierarchy for Folder2
  Folder2
    Folder1
        File1
    File2
    File3

Printing hierarchy for clone Folder
  Folder2_clone
    Folder1_clone
        File1_clone
    File2_clone
    File3_clone

Prototype en otros lenguajes

Prototype en C# Prototype en C++ Prototype en Java Prototype en PHP Prototype en Python Prototype en Ruby Prototype en Rust Prototype en Swift Prototype en TypeScript