Home > Backend Development > Golang > How to Register Go Package Implementations Without Creating Cyclic Dependencies?

How to Register Go Package Implementations Without Creating Cyclic Dependencies?

Barbara Streisand
Release: 2024-12-29 14:01:10
Original
207 people have browsed it

How to Register Go Package Implementations Without Creating Cyclic Dependencies?

Registering Packages in Go without Cyclic Dependency

When designing a Go application, it's crucial to avoid cyclic dependencies between packages, where one package depends on another, which in turn depends on the first. This can arise when defining interfaces and their implementations across multiple packages.

Question:

How can we register client implementations without creating a cyclic dependency between our central package (with the client interface) and the packages containing the implementations (e.g., UDPClient, TCPClient)?

Answer:

The standard library offers two main approaches to address this issue:

1. Without a Central Registry

Define the client interface in a central package. For implementation, explicitly specify the desired implementation when instantiating clients. For example:

import (
    "hash/md5"
    "hash/sha256"
)

func main() {
    h1 := md5.New()
    h2 := sha256.New()
}
Copy after login

2. With a Central Registry

Create a registry mechanism where implementations register themselves. This approach is similar to the spontaneous registration discussed in the question. It's used in the image package, where various image format decoders (e.g., GIF, JPEG, PNG) register themselves.

3. Proposed Custom Registry

Introduce a separate factory package that provides the NewClient() methods for creating clients. This package can refer to the interface and implementation packages without causing a circular dependency. For instance:

package pi

// Client represents the client interface.
type Client interface { ... }
Copy after login
package pa

// UDPClient implements the Client interface.
type UDPClient struct { ... }
Copy after login
package pb

// TCPClient implements the Client interface.
type TCPClient struct { ... }
Copy after login
package pf

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

// NewClient creates a client based on the implementation.
func NewClient(impl string) pi.Client {
    switch impl {
    case "udp":
        return &pa.UDPClient{}
    case "tcp":
        return &pb.TCPClient{}
    default:
        panic("Unsupported implementation")
    }
}
Copy after login

The above is the detailed content of How to Register Go Package Implementations Without Creating Cyclic Dependencies?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template