Глянь мій новий курс по Git! Привіт! Глянь мій новий курс по Git! Привіт! Глянь мій новий курс по Git на GitByBit.com! Привіт! Хочеш класно освіжити Git? Глянь мій новий курс на GitByBit.com!
Прототип

Прототип на Go

Прототип — це породжуючий патерн, який дозволяє копіювати об’єкти будь-якої складності без прив’язки до їхніх конкретних класів.

Усі класи-Прототипи мають спільний інтерфейс. Тому ви можете копіювати об’єкти, не звертаючи уваги на їхні конкретні типи та бути завжди впевненими в тому, що отримаєте точну копію. Клонування здійснюється самим об’єктом-прототипу, що дозволяє йому скопіювати значення всіх полів, навіть приватних.

Концептуальний приклад

Давайте спробуємо розібрати патерн Прототип, використовуючи за приклад файлову систему ОС. Файлова система є рекурсивною — папки містять файли та інші папки, які, в свою чергу, можуть містити файли та папки, і так далі.

Кожен файл і папка можуть бути представлені інтерфейсом inode. Він має функцію clone.

Обидві структури файлу й папки — file і folder — реалізують функції print і clone, оскільки вони мають тип inode. Також, зверніть увагу на функцію clone в file і folder. Функція clone в обох випадках повертає копію відповідного файлу або папки. Під час клонування ми додаємо ключове слово «_clone» в поле імені.

inode.go: Інтерфейс прототипа

package main

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

file.go: Конкретний прототип

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: Конкретний прототип

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: Клієнтський код

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: Результат виконання

Printing hierarchy for Folder2
  Folder2
    Folder1
        File1
    File2
    File3

Printing hierarchy for clone Folder
  Folder2_clone
    Folder1_clone
        File1_clone
    File2_clone
    File3_clone
На основі: Golang By Example

Прототип іншими мовами програмування

Прототип на C# Прототип на C++ Прототип на Java Прототип на PHP Прототип на Python Прототип на Ruby Прототип на Rust Прототип на Swift Прототип на TypeScript