Hourra ! La version française est enfin sortie ! Laissez-nous un message svp, si vous voulez nous faire part de vos commentaires ou signaler une erreur.
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 qui rend 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 + "_clone")
}

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

folder.go: Prototype concret

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

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

Patrons de conception : Prototype en Java Patrons de conception : Prototype en C# Patrons de conception : Prototype en C++ Patrons de conception : Prototype en PHP Patrons de conception : Prototype en Python Patrons de conception : Prototype en Ruby Patrons de conception : Prototype en Swift Patrons de conception : Prototype en TypeScript