0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Go]埋め込み

Last updated at Posted at 2023-03-06

概要

とあるPRで、構造体をインターフェース化するように言われたけど、愚直に実装しようとすると処理が共通なところ多いなぁ・・・なんとかできないかなぁ・・・と調べているとで、Goだと埋め込み(embed)がこの事態の解決にもっともふさわしそうということで、マジメにまとめてみた。

埋め込み

Goで「委譲」を実現する機能。

継承と委譲

  • 継承は「is-a」、委譲は「has-a」の関係。
  • 継承の目的は既存のコードを拡張して新しいクラスを作ること、委譲の目的はその名の通り、一部の機能の処理をおまかせすること。
  • Goのembedは「委譲」にあたり「継承」はできないので、概念的に「A is B」な構造体間の関係だったとしても、「A has B」として実装する形になりそう。親構造体を子構造体がフィールドとして持つ感じ。

構造体の埋め込みとインターフェースとのあわせ技

実務での要件的に、以下のような感じで設計することがあったので、将来的な参考としてメモ。

  • インターフェース定義(型定義はexported)
    • 外部公開したいメソッドをexportedで定義する
      • データを参照したいものはすべてGetterとして定義しておく
  • 埋め込み元の構造体定義(継承でいうところの親クラス的な位置づけ)(型定義はunexported)
    • インターフェースの実装となるメソッドの定義(※インターフェース定義を単独で満たす)(型定義はunexported)
      • これらを支えるサブルーチンメソッドの定義(unexported)
    • 処理に必要になるフィールドの定義(unexported)
    • コンストラクタを定義(返り値は構造体)
  • 埋め込み先の構造体定義(継承でいうところの子クラス的な位置づけ)(型定義はunexported)
    • 埋め込み元の構造体をフィールドとして定義する
    • 固有の処理につかいたいフィールドの定義(unexported)
    • オーバーライド的に定義したいメソッド(exported)や、それらを支える独自のメソッド(unexported)を定義する
    • コンストラクタを定義(返り値はインターフェース)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?