循環依存関係を持たずに Go にパッケージを登録する
Go アプリケーションを設計するときは、1 つのパッケージが依存するパッケージ間の循環依存関係を避けることが重要です。別のものに依存し、それが最初のものに依存します。これは、複数のパッケージにわたってインターフェイスとその実装を定義するときに発生する可能性があります。
質問:
中央のパッケージ (クライアント インターフェイス)と実装を含むパッケージ(例: UDPClient、 TCPClient)?
回答:
標準ライブラリでは、この問題に対処するための 2 つの主なアプローチが提供されています。
1.中央レジストリを使用しない
中央パッケージでクライアント インターフェイスを定義します。実装については、クライアントをインスタンス化するときに、目的の実装を明示的に指定します。例:
import ( "hash/md5" "hash/sha256" ) func main() { h1 := md5.New() h2 := sha256.New() }
2.中央レジストリを使用する
実装が自身を登録するレジストリ メカニズムを作成します。このアプローチは、質問で説明した自発的登録に似ています。これは、さまざまな画像形式デコーダー (GIF、JPEG、PNG など) が自身を登録する画像パッケージで使用されます。
3.提案されたカスタム レジストリ
クライアントを作成するための NewClient() メソッドを提供する別のファクトリー パッケージを導入します。このパッケージは、循環依存関係を引き起こすことなく、インターフェイスおよび実装パッケージを参照できます。例:
package pi // Client represents the client interface. type Client interface { ... }
package pa // UDPClient implements the Client interface. type UDPClient struct { ... }
package pb // TCPClient implements the Client interface. type TCPClient struct { ... }
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") } }
以上が循環依存関係を作成せずに Go パッケージ実装を登録するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。