問題の概要:
目標: 再利用可能な基本構造体を作成する他の構造体によって拡張できるメソッド。ただし、Go の構造では親構造体のメソッドへのアクセスが制限されているため、従来の継承は不可能です。
元のパターン:
ユーザーは継承のような動作を伴う複雑なパターンを提案します:
type MyInterface interface { SomeMethod(string) OtherMethod(string) } type Base struct{ B MyInterface } func (b *Base) SomeMethod(x string) { b.B.OtherMethod(x) } type Extender struct { Base } func (b *Extender) OtherMethod(x string) { // Do something... } func NewExtender() *Extender { e := Extender{} e.Base.B = &e return &e }
Go のアプローチ: 構成終了継承
Go は、柔軟性と保守性を高めるために、継承よりも合成を奨励します。 Go では、サブクラス化の代わりに、インターフェイスと構造体の埋め込みを使用して拡張性を実現します。
Embedding:
Embedding を使用すると、構造体に別の構造体のフィールドとメソッドを直接組み込むことができ、効果的に再利用できます。その機能性。たとえば、Reader と Writer インターフェイスがある場合、結合した ReadWriter インターフェイスを作成し、Reader と Writer の実装を埋め込むことができます。
type Reader interface { Read(p []byte) (n int, err error) } type Writer interface { Write(p []byte) (n int, err error) } type ReadWriter interface { Reader Writer } type MyReadWriter struct { *MyReader *MyWriter // Additional ReadWriter-specific methods if needed }
MyReadWriter 構造体は、両方の MyReader からのすべてのメソッドにアクセスして使用できるようになりました。
依存関係インジェクション:
埋め込みにより依存関係の注入も容易になり、より適切なテストと分離が可能になります。 MyReader と MyWriter を MyReadWriter 構造体に注入すると、依存関係が明示的に渡されるようになり、テスト容易性が向上します。
使用例:
func (rw *MyReadWriter) DoCrazyStuff() { data := []byte{} // Do stuff... rw.Read(data) rw.Write(data) // You get the idea... } func main() { rw := &MyReadWriter{&MyReader{}, &MyWriter{}} rw.DoCrazyStuff() }
この例では、たとえば、rw 構造体はリーダーとライターの両方として機能するため、さまざまな用途で多用途に使用できます。シナリオ。
以上が従来の継承を使用せずに、Go で継承のような拡張性を実現するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。