Modèles de conception avancés en Go avec exemples de code

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Modèles de conception avancés en Go : de la théorie à la pratique



Go (Golang) est un langage qui encourage la simplicité et la lisibilité du code. Cependant, lorsque le projet s'agrandit, même le code le plus concis peut se transformer en chaos sans une architecture appropriée. Au niveau avancé, les développeurs Go utilisent activement des modèles de conception adaptés aux spécificités du langage : goroutines, canaux, interfaces et génériques (depuis Go 1.18+).



Dans cet article, nous allons analyser 4 modèles puissants qui vous aideront à écrire du code Go évolutif, testable et performant. Chaque modèle est accompagné d'un exemple pratique.



1. Modèle Pipeline (Convoyeur) pour le traitement de données en flux



Pipeline est l'un des modèles les plus populaires en Go pour le traitement séquentiel des données. Il s'intègre parfaitement au modèle des goroutines et des canaux. Chaque étape de traitement est exécutée dans une goroutine distincte, et les données sont transmises via des canaux.



Quand l'utiliser : Traitement de logs, transformation de données, processus ETL, vidéo en flux.



Exemple : Convoyeur pour le filtrage et la transformation de nombres.



package main

import "fmt"

// Stage 1 : Génération de nombresfunc generate(nums ...int) <-chan int { out := make(chan int) go func() { for _, n := range nums { out <- n } close(out) }() return out}

// Stage 2 : Multiplication par 2func multiply(in <-chan int) <-chan int { out := make(chan int) go func() { for n := range in { out <- n * 2 } close(out) }() return out}

// Stage 3 : Filtrage (uniquement les pairs)func filterEven(in <-chan int) <-chan int { out := make(chan int) go func() { for n := range in { if n%2 == 0 { out <- n } } close(out) }() return out}

func main() { // Assemblage du convoyeur pipeline := filterEven(multiply(generate(1, 2, 3, 4, 5)))

for result := range pipeline { fmt.Println(result) // Sortie : 4, 8 (uniquement les pairs après multiplication) }}


Avantages : Traitement parallèle naturel, faible consommation mémoire (les données ne s'accumulent pas), facilité d'ajout de nouvelles étapes.



2. Fan-Out / Fan-In : mise à l'échelle du traitement



Ce modèle est une évolution avancée du Pipeline. Fan-Out (ramification) lance plusieurs goroutines pour traiter en parallèle les données provenant d'un seul canal. Fan-In (fusion) rassemble les résultats de plusieurs canaux en un seul.



Quand l'utiliser : Analyse de pages web, traitement d'un grand nombre de fichiers, requêtes parallèles à une API.



Exemple : Vérification parallèle de la disponibilité d'URL.



package main

import ( "fmt" "net/http" "sync")

func worker(urls <-chan string, results chan<- string, wg *sync.WaitGroup) { defer wg.Done() for url := range urls { resp, err := http.Get(url) if err != nil { results <- fmt.Sprintf("Erreur : %s - %v", url, err) continue } resp.Body.Close() results <- fmt.Sprintf("OK : %s - %d", url, resp.StatusCode) }}

func fanOutFanIn(urls []string, numWorkers int) []string { urlChan := make(chan string, len(urls)) resultChan := make(chan string, len(urls)) var wg sync.WaitGroup

// Fan-Out : lancement des workers for i := 0; i < numWorkers; i++ { wg.Add(1) go worker(urlChan, resultChan, &wg) }

// Envoi des URL for _, url := range urls { urlChan <- url } close(urlChan)

// Attente de la fin de tous les workers wg.Wait() close(resultChan)

// Fan-In : collecte des résultats var results []string for res := range resultChan { results = append(

Blogs

Book Recommendations