Spring SALE
Prototype

Prototype en Go

Le Prototype est un patron de conception de création qui permet de cloner des objets - même complexes - sans se coupler à leur classe.

Toutes les classes prototype devraient avoir une interface commune rendant possible la copie des objets, même sans connaître leur classe concrète. Les objets prototype peuvent créer des copies complètes puisqu’ils peuvent accéder aux attributs privés des autres objets de la même classe.

Exemple conceptuel

Essayons de comprendre le prototype en utilisant un exemple basé sur le système de fichiers d’un système d’exploitation (SE). Le système de fichier du SE est récursif : les dossiers contiennent des fichiers et des dossiers, qui peuvent eux-mêmes inclure des fichiers et des dossiers, et ainsi de suite.

Chaque fichier/dossier est représenté par une interface inode. L’interface inode possède également la fonction clone.

Les structs file et folder implémentent les fonctions print et clone, car elles sont du type inode. Vous pourrez également remarquer la fonction clone dans file et folder qui retourne une copie correspondante pour chacun d’entre eux. Durant le clonage, nous suffixons le nom de l’attribut avec « _clone ».

inode.go: Interface du prototype

package main

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

file.go: Prototype concret

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: Prototype concret

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: Code client

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: Résultat de l’exécution

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 dans les autres langues

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