Hura! Mamy wreszcie przyjemność udostępnić wam polską wersję! Zapraszamy do przesyłania wiadomości z waszymi uwagami i informacjami o zauważonych błędach.
Prototyp

Prototyp w języku Go

Prototyp To kreacyjny wzorzec projektowy pozwalający klonować obiekty — również te złożone — bez konieczności sprzęgania z ich klasami.

Wszystkie klasy prototyp powinny mieć wspólny interfejs który pozwoli kopiować ich obiekty nawet gdy nie zna się ich konkretnych klas. Obiekty-prototypy mogą tworzyć kompletne kopie, ponieważ pola prywatne danej klasy są dostępne dla innych obiektów tej samej klasy.

Przykład koncepcyjny

Spróbujmy pojąć wzorzec Prototyp na przykładzie odnoszącym się do systemu plików systemu operacyjnego. System plików jest rekursywny: foldery zawierają pliki i inne foldery, które również mogą zawierać pliki i foldery i tak dalej.

Każdy plik i folder można przedstawić stosując interfejs inode. Interfejs inode zawiera także funkcję clone.

Zarówno struktury file jak i folder implementują funkcje print i clone gdyż są one typu inode. Zwróćmy też uwagę, że funkcja clone w file i w folder zwraca kopię — odpowiednio — pliku lub folderu. W momencie klonowania do pola nazwy dołączamy słowo kluczowe “_clone”.

inode.go: Prototype interface

package main

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

file.go: Concrete prototype

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: Concrete prototype

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: Kod klienta

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: Wynik działania

Printing hierarchy for Folder2
  Folder2
    Folder1
        File1
    File2
    File3

Printing hierarchy for clone Folder
  Folder2_clone
    Folder1_clone
        File1_clone
    File2_clone
    File3_clone
Na podstawie: Golang By Example

Prototyp w innych językach

Wzorce projektowe: Prototyp w języku Java Wzorce projektowe: Prototyp w języku C# Wzorce projektowe: Prototyp w języku C++ Wzorce projektowe: Prototyp w języku PHP Wzorce projektowe: Prototyp w języku Python Wzorce projektowe: Prototyp w języku Ruby Wzorce projektowe: Prototyp w języku Swift Wzorce projektowe: Prototyp w języku TypeScript