Maison >développement back-end >Golang >Comment enregistrer des packages Go sans créer de dépendances cycliques ?

Comment enregistrer des packages Go sans créer de dépendances cycliques ?

DDD
DDDoriginal
2024-12-21 06:52:10908parcourir

How to Register Go Packages Without Creating Cyclic Dependencies?

Enregistrement de packages dans Go sans dépendance cyclique

Problème :

Vous disposez d'un package central qui fournit des interfaces et dépend de d'autres packages qui offrent des implémentations de ces interfaces. Cependant, l'inclusion de ces packages dépendants dans le package central crée une dépendance cyclique, ce que Go ne permet pas.

Solutions de bibliothèque standard :

  • Sans Registre central : Définissez les interfaces dans un seul package et les implémentations concrètes dans des packages séparés. L'utilisateur spécifie explicitement quelle implémentation utiliser.
  • Avec le registre central : Les implémentations s'enregistrent elles-mêmes dans un registre central (souvent via les fonctions du package init()). Cela permet une extensibilité mais nécessite un enregistrement manuel.

Solution de registre personnalisé :

  • Créez un package supplémentaire (pf) qui fournit des méthodes « d'usine » pour instancier des implémentations spécifiques.
  • Le package d'usine dépend à la fois du package d'interface (pi) et des packages d'implémentation (pa, pb, etc.), mais cela ne crée pas de cycle car pf ne dépend pas de lui-même.

Choisir la meilleure solution :

L'approche idéale dépend d'exigences spécifiques :

  • Si vous pouvez prédéterminer l'implémentation à utiliser, optez pour la première solution (sans centrale registre).
  • Si l'extensibilité est critique et que vous ne pouvez pas prédire la mise en œuvre, envisagez la deuxième ou la troisième solution (avec un registre central ou personnalisé).

Exemple de code pour Solution de registre personnalisé :

// Package pi defines an interface I.
package pi

type I interface {
    // Some method.
    DoSomething()
}

// Package pa implements I with type A.
package pa

import "pi"

type A struct{}

func (a *A) DoSomething() {
    // Some implementation.
}

// Package pb implements I with type B.
package pb

import "pi"

type B struct{}

func (b *B) DoSomething() {
    // Some implementation.
}

// Package pf provides a factory to create instances of I.
package pf

import (
    "pi"
    "pa"
    "pb"
)

// NewClient returns an instance of I based on a flag.
func NewClient(flag string) pi.I {
    switch flag {
    case "a":
        return &pa.A{}
    case "b":
        return &pb.B{}
    default:
        panic("Invalid flag")
    }
}

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