この記事は Best Practices for Interfaces in Go を翻訳したものです(抄訳です)。
誤訳がある可能性があるため、リンク先の元記事をあらためて参照お願いします。
Golang におけるinterface とは何か
ほかのtype が実装できるカスタムtype のこと
これによって高い抽象度を得ることができる
他のtype が全てのメソッドを実祖した時に実装できる
interface のベストプラクティス
そもそも綺麗なインターフェースを書くのは難しい
シンプルなコードもすぐに複雑になる
下記の3点を守れば綺麗なままでいられる
- interface は小さく作る
- interface には知識を入れない
- interface をclass のように扱わない
interface は小さく作る
本記事に置いて最重要なトピック
interfaceはアイデアやコンセプトを表すための最小の必要な振る舞いの定義を意味している
HTTP Package が最小の振る舞いを定義している良い例
File として扱われると思われる振る舞いを定義しており、disk, newwork buffer, []byte のどれで扱われるかは考えていない
interface には知識を入れない
interface は必要な振る舞いが定義されるべきであり、何が起こるかについては考えるべきではない
type car interface {
Color() string
Speed() int
IsFiretruck() bool
}
上記のコードにおいて、IsFiretruck()
はアンチパターンになっている。
この定義だと、全ての車は自分が消防車かどうかを気にする必要が出てくる
パトカー、救急車、セダンのように、全ての属性に対してIsXXX()を定義する必要が出てきてしまう
基礎的なCar interface を使うか、
type firetruck interface {
car
HoseLength() int
}
を定義する方が良い
interface をclass のように扱わない
interface はclass に似ているが、別物である
コンストラクトやデコンストラクタは持ってないし、データを作ったり消したりしない
interface は自然な階層ではないので、他のinterfae のsuperset になるinterface を作成するための構造的な甘さがある
interface は関数署名をで意義するが、基礎として振る舞うことはない。interface を作成するときは、struct methods に関してコード上で同じコードを書かないように作成する
例えば、5つのtype がerror interface を満たした場合、5つの異なる振る舞いをするErrors() 関数が必要になる