Menu
Coddy logo textTech

Chaînage de méthodes

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 81 sur 107.

Le chaînage de méthodes (method chaining) est une technique où les méthodes retournent le receveur, permettant de lier plusieurs appels de méthodes en une seule instruction. Vous avez déjà vu cela dans le patron Builder, mais c'est un concept autonome utile dans de nombreux contextes.

La clé est de retourner un pointeur vers la struct à partir de chaque méthode :

type Query struct {
    table   string
    columns []string
    where   string
    limit   int
}

func (q *Query) Select(cols ...string) *Query {
    q.columns = cols
    return q
}

func (q *Query) From(table string) *Query {
    q.table = table
    return q
}

func (q *Query) Where(condition string) *Query {
    q.where = condition
    return q
}

func (q *Query) Limit(n int) *Query {
    q.limit = n
    return q
}

Maintenant, vous pouvez chaîner ces appels de manière fluide :

query := &Query{}
query.Select("name", "email").From("users").Where("active = true").Limit(10)

Cela se lit presque comme du langage naturel par rapport à des instructions séparées. Le chaînage de méthodes fonctionne mieux lorsque les opérations configurent ou modifient un objet sans avoir besoin de renvoyer d'autres valeurs. Il est couramment utilisé dans les générateurs de requêtes, les API de configuration et les bibliothèques d'assertions de test.

N'oubliez pas que chaque méthode doit utiliser un récepteur de pointeur et retourner *StructType pour que le chaînage fonctionne correctement.

challenge icon

Défi

Facile

Construisons un générateur d'éléments HTML fluide qui utilise le chaînage de méthodes pour construire des balises HTML avec des attributs et du contenu ! Il s'agit d'une application pratique du chaînage de méthodes — vous allez créer une API qui se lit presque comme un langage naturel lors de la construction d'éléments HTML.

Vous organiserez votre code sur deux fichiers :

  • element.go : Définissez votre générateur d'éléments HTML avec des méthodes chaînables.

    Créez une structure Element qui stocke le nom de la balise, une map d'attributs (chaîne vers chaîne) et le contenu interne. Construisez ces méthodes chaînables qui retournent chacune *Element :

    • NewElement(tag string) - constructeur qui crée un nouvel Element avec le nom de balise donné et une map d'attributs initialisée (vide)
    • Attr(key, value string) - ajoute un attribut à l'élément
    • ID(id string) - méthode de commodité qui définit l'attribut "id"
    • Class(class string) - méthode de commodité qui définit l'attribut "class"
    • Content(text string) - définit le contenu interne de l'élément

    Ajoutez une méthode Render() qui retourne la chaîne HTML. Les attributs doivent apparaître par ordre alphabétique de clé. Le format est :

    <tag attr1="value1" attr2="value2">content</tag>

    S'il n'y a pas d'attributs, affichez simplement <tag>content</tag>. S'il n'y a pas de contenu, affichez <tag attr="value"></tag>.

  • main.go : Construisez des éléments HTML en utilisant le chaînage de méthodes.

    Lisez le nom de la balise, puis lisez le nombre d'opérations à effectuer. Chaque opération est l'une des suivantes :

    • id suivi de la valeur de l'ID
    • class suivi de la valeur de la classe
    • attr suivi du nom de l'attribut et de sa valeur (deux lignes)
    • content suivi du texte du contenu

    Chaînez toutes les opérations ensemble de manière fluide, puis affichez le HTML généré.

Les entrées suivantes seront fournies :

  • Ligne 1 : Nom de la balise
  • Ligne 2 : Nombre d'opérations
  • Lignes suivantes : Type d'opération et valeur(s)

Par exemple, avec :

div
3
id
container
class
main-content
content
Hello World

Votre sortie devrait être :

<div class="main-content" id="container">Hello World</div>

Et avec :

a
3
attr
href
https://example.com
attr
target
_blank
content
Click here

Votre sortie devrait être :

<a href="https://example.com" target="_blank">Click here</a>

Et avec :

input
2
attr
type
text
attr
placeholder
Enter name

Votre sortie devrait être :

<input placeholder="Enter name" type="text"></input>

Et avec :

p
1
content
Simple paragraph

Votre sortie devrait être :

<p>Simple paragraph</p>

Remarquez comment le chaînage de méthodes vous permet de construire des éléments étape par étape de manière lisible. Chaque méthode modifie l'élément et le retourne, permettant à l'appel de méthode suivant d'être chaîné directement.

Aide-mémoire

Le chaînage de méthodes est une technique où les méthodes retournent le récepteur (généralement *StructType), permettant à plusieurs appels de méthodes d'être liés ensemble dans une seule instruction.

Chaque méthode doit utiliser un récepteur de pointeur et retourner *StructType :

type Query struct {
    table   string
    columns []string
    where   string
    limit   int
}

func (q *Query) Select(cols ...string) *Query {
    q.columns = cols
    return q
}

func (q *Query) From(table string) *Query {
    q.table = table
    return q
}

func (q *Query) Where(condition string) *Query {
    q.where = condition
    return q
}

func (q *Query) Limit(n int) *Query {
    q.limit = n
    return q
}

Enchaînez les appels de méthodes de manière fluide :

query := &Query{}
query.Select("name", "email").From("users").Where("active = true").Limit(10)

Le chaînage de méthodes fonctionne mieux lorsque les opérations configurent ou modifient un objet sans avoir besoin de retourner d'autres valeurs. Il est couramment utilisé dans les constructeurs de requêtes (query builders), les API de configuration et les bibliothèques d'assertions de test.

Essayez vous-même

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	// Lire le nom de la balise
	scanner.Scan()
	tagName := scanner.Text()

	// Lire le nombre d'opérations
	scanner.Scan()
	numOps, _ := strconv.Atoi(scanner.Text())

	// Créer l'élément
	element := NewElement(tagName)

	// Traiter chaque opération
	for i := 0; i < numOps; i++ {
		scanner.Scan()
		operation := scanner.Text()

		// TODO : Selon le type d'opération, enchaîner la méthode appropriée
		// Les opérations peuvent être : "id", "class", "attr", ou "content"
		// - Pour "id" : lire la ligne suivante comme valeur de l'ID
		// - Pour "class" : lire la ligne suivante comme valeur de la classe
		// - Pour "attr" : lire les DEUX lignes suivantes (nom de l'attribut, puis valeur)
		// - Pour "content" : lire la ligne suivante comme texte du contenu
		// Utiliser le chaînage de méthodes pour construire l'élément de manière fluide

		_ = operation // Supprimer cette ligne lors de l'implémentation
	}

	// Afficher le HTML rendu
	fmt.Println(element.Render())
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet