Viva! A versão em Português Brasileiro finalmente foi lançada! Por favor, envie-nos uma mensagem se você quer compartilhar sua opinião ou relatar um erro.
Prototype

Prototype em Go

O Prototype é um padrão de projeto criacional que permite a clonagem de objetos, mesmo complexos, sem acoplamento à suas classes específicas.

Todas as classes de prototypes(protótipos) devem ter uma interface comum que permita copiar objetos, mesmo que suas classes concretas sejam desconhecidas. Objetos protótipos podem produzir cópias completas, pois objetos da mesma classe podem acessar os campos privados um do outro.

Exemplo conceitual

Vamos tentar descobrir o padrão Prototype usando um exemplo baseado no sistema de arquivos do sistema operacional. O sistema de arquivos do SO é recursivo: as pastas contêm arquivos e pastas, que também podem incluir arquivos e pastas e assim por diante.

Cada arquivo e pasta pode ser representado por uma interface inode. A interface inode também possui a função clone.

Ambas as structs file e folder implementam as funções print e clone, uma vez que são do tipo inode. Além disso, observe a função clone em file e folder. A função clone em ambos retorna uma cópia do respectivo arquivo ou pasta. Durante a clonagem, acrescentamos a palavra-chave “_clone” ao campo de nome.

inode.go: Interface do prototype

package main

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

file.go: Prototype concreto

package main

import "fmt"

type file struct {
	name string
}

func (f *file) print(indentation string) {
	fmt.Println(indentation + f.name + "_clone")
}

func (f *file) clone() inode {
	return &file{name: f.name}
}

folder.go: Prototype concreto

package main

import "fmt"

type folder struct {
	childrens []inode
	name      string
}

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

func (f *folder) clone() inode {
	cloneFolder := &folder{name: f.name + "_clone"}
	var tempChildrens []inode
	for _, i := range f.childrens {
		copy := i.clone()
		tempChildrens = append(tempChildrens, copy)
	}
	cloneFolder.childrens = tempChildrens
	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{
		childrens: []inode{file1},
		name:      "Folder1",
	}

	folder2 := &folder{
		childrens: []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: Resultados da execução

Printing hierarchy for Folder2
  Folder2
    Folder1
        File1
    File2
    File3

Printing hierarchy for clone Folder
  Folder2_clone
    Folder1_clone
        File1_clone
    File2_clone
    File3_clone
Baseado em: Golang By Example

Prototype em outras linguagens

Padrões de Projeto: Prototype em Java Padrões de Projeto: Prototype em C# Padrões de Projeto: Prototype em C++ Padrões de Projeto: Prototype em PHP Padrões de Projeto: Prototype em Python Padrões de Projeto: Prototype em Ruby Padrões de Projeto: Prototype em Swift Padrões de Projeto: Prototype em TypeScript