Maison développement back-end Golang Modèle d'options fonctionnelles dans Go

Modèle d'options fonctionnelles dans Go

Nov 19, 2024 pm 12:52 PM

Functional Options Pattern in Go

Dans le développement de logiciels, la flexibilité dans la configuration des objets est un besoin courant, en particulier lorsqu'il s'agit de fonctions et de structures avec plusieurs paramètres facultatifs.

Dans Go, comme il ne prend pas en charge la surcharge de fonctions, trouver une solution élégante à ce problème peut être difficile. C'est là que le modèle d'options fonctionnelles entre en jeu en tant qu'approche efficace et idiomatique.

Qu'est-ce que le modèle d'options fonctionnelles ?

Le Functional Options Pattern est un modèle de conception largement utilisé dans Go pour faciliter la configuration de structures ou de fonctions complexes, notamment lorsqu'il existe plusieurs paramètres facultatifs. Il vous permet de créer des objets ou de configurer des fonctions de manière flexible en utilisant des fonctions qui agissent comme des « options ».

Au lieu de transmettre directement tous les paramètres à un constructeur ou à une fonction, vous créez des fonctions distinctes qui appliquent des configurations incrémentielles et facultatives. Cette approche permet d'éviter les fonctions avec de longues listes de paramètres ou la nécessité de plusieurs constructeurs pour différents cas d'utilisation.

L'appliquer dans la pratique

Considérons un problème courant dans le développement d'API : la création d'un client HTTP personnalisé, où certaines configurations (comme le délai d'attente, les en-têtes et les tentatives) sont facultatives. Sans le modèle d'options fonctionnelles, vous devrez transmettre tous les paramètres possibles à la fonction de création, ce qui entraînerait un code moins lisible et plus difficile à maintenir.

Création d'un client HTTP avec des paramètres facultatifs

Supposons que nous souhaitions créer un client HTTP qui nous permet de définir un délai d'attente facultatif, un en-tête personnalisé* et le nombre de tentatives (tentatives de reconnexion). La solution traditionnelle sans le modèle d'options fonctionnelles ressemblerait à ceci :

type HttpClient struct {
    Timeout time.Duration
    Headers map[string]string
    Retries int
}

func NewHttpClient(timeout time.Duration, headers map[string]string, retries int) *HttpClient {
    return &HttpClient{
        Timeout: timeout,
        Headers: headers,
        Retries: retries,
    }
}
Copier après la connexion

Si vous ne souhaitez pas définir tous les paramètres, vous devrez quand même transmettre des valeurs par défaut ou zéro, ce qui pourrait prêter à confusion et gêner la lisibilité.

Voyons maintenant comment appliquer le modèle d'options fonctionnelles pour améliorer cette approche.

Implémentation du modèle d'options fonctionnelles

Ici, nous utiliserons des fonctions qui encapsulent des options, vous permettant de configurer uniquement les paramètres dont vous avez réellement besoin.

type HttpClient struct {
    Timeout time.Duration
    Headers map[string]string
    Retries int
}

// Option defines the function type that will apply settings to HttpClient
type Option func(*HttpClient)

// NewHttpClient creates an HttpClient instance with functional options
func NewHttpClient(opts ...Option) *HttpClient {
    client := &HttpClient{
        Timeout: 30 * time.Second, // default value
        Headers: make(map[string]string),
        Retries: 3, // default value
    }

    // Apply the provided options
    for _, opt := range opts {
        opt(client)
    }

    return client
}

// WithTimeout allows you to set the client timeout
func WithTimeout(timeout time.Duration) Option {
    return func(c *HttpClient) {
        c.Timeout = timeout
    }
}

// WithHeaders allows you to add custom headers
func WithHeaders(headers map[string]string) Option {
    return func(c *HttpClient) {
        for k, v := range headers {
            c.Headers[k] = v
        }
    }
}

// WithRetries allows you to set the number of reconnection attempts
func WithRetries(retries int) Option {
    return func(c *HttpClient) {
        c.Retries = retries
    }
}
Copier après la connexion

Désormais, lors de la création d'un nouveau client HTTP, vous pouvez spécifier uniquement les options souhaitées :

func main() {
    client := NewHttpClient(
        WithTimeout(10*time.Second),
        WithHeaders(map[string]string{"Authorization": "Bearer token"}),
    )

    fmt.Printf("Timeout: %v, Headers: %v, Retries: %d\n", client.Timeout, client.Headers, client.Retries)
}
Copier après la connexion

Cela permet flexibilité et clarté dans la configuration du client sans avoir besoin de transmettre tous les paramètres à chaque fois.

Packages qui utilisent ce modèle

De nombreux packages populaires de l'écosystème Go utilisent le modèle d'options fonctionnelles. Des exemples notables incluent :

  • grpc-go : le package Go pour gRPC utilise des options fonctionnelles pour configurer les serveurs et les clients gRPC.

  • zap : l'enregistreur hautes performances populaire utilise ce modèle pour configurer plusieurs options de journalisation, telles que le niveau de journalisation, le format de sortie, etc.

Conclusion

Le modèle d'options fonctionnelles est une solution puissante et idiomatique dans Go pour gérer des fonctions ou des structures qui nécessitent une configuration flexible. En adoptant ce modèle, vous améliorez la lisibilité du code, offrez de la flexibilité aux utilisateurs finaux et évitez la prolifération de fonctions avec des listes de paramètres étendues.

Qu'il s'agisse de créer un client HTTP personnalisé ou de configurer une bibliothèque complexe, le modèle d'options fonctionnelles est un outil précieux pour concevoir des API dans Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

GO Language Pack Import: Quelle est la différence entre le soulignement et sans soulignement? GO Language Pack Import: Quelle est la différence entre le soulignement et sans soulignement? Mar 03, 2025 pm 05:17 PM

GO Language Pack Import: Quelle est la différence entre le soulignement et sans soulignement?

Comment mettre en œuvre le transfert d'informations à court terme entre les pages du cadre Beego? Comment mettre en œuvre le transfert d'informations à court terme entre les pages du cadre Beego? Mar 03, 2025 pm 05:22 PM

Comment mettre en œuvre le transfert d'informations à court terme entre les pages du cadre Beego?

Comment convertir la liste des résultats de la requête MySQL en une tranche de structure personnalisée dans le langage Go? Comment convertir la liste des résultats de la requête MySQL en une tranche de structure personnalisée dans le langage Go? Mar 03, 2025 pm 05:18 PM

Comment convertir la liste des résultats de la requête MySQL en une tranche de structure personnalisée dans le langage Go?

Comment puis-je définir des contraintes de type personnalisé pour les génériques en Go? Comment puis-je définir des contraintes de type personnalisé pour les génériques en Go? Mar 10, 2025 pm 03:20 PM

Comment puis-je définir des contraintes de type personnalisé pour les génériques en Go?

Comment écrire des objets et des talons simulés pour les tests en Go? Comment écrire des objets et des talons simulés pour les tests en Go? Mar 10, 2025 pm 05:38 PM

Comment écrire des objets et des talons simulés pour les tests en Go?

Comment écrire des fichiers dans GO Language de manière pratique? Comment écrire des fichiers dans GO Language de manière pratique? Mar 03, 2025 pm 05:15 PM

Comment écrire des fichiers dans GO Language de manière pratique?

Comment rédigez-vous des tests unitaires en Go? Comment rédigez-vous des tests unitaires en Go? Mar 21, 2025 pm 06:34 PM

Comment rédigez-vous des tests unitaires en Go?

Comment puis-je utiliser des outils de traçage pour comprendre le flux d'exécution de mes applications GO? Comment puis-je utiliser des outils de traçage pour comprendre le flux d'exécution de mes applications GO? Mar 10, 2025 pm 05:36 PM

Comment puis-je utiliser des outils de traçage pour comprendre le flux d'exécution de mes applications GO?

See all articles