クリーンインターフェイスを書くためのベストプラクティス



インターフェイスを使用すると、特定の動作と同じ種類の型を扱うことができます.彼らはGOプログラマのツールベルトの中心であり、しばしば新しいGO開発者によって不適切に使用されます.
インターフェイスはメソッドシグネチャのコレクションと名付けられます.

インタフェースの要約


きれいな試みを書く方法の例として標準ライブラリを見てみましょう.エラーインターフェイスは単純です.
type error interface {
    Error() string
}
定義によって、エラーインターフェイスは、Error ()メソッドが定義されている型をカプセル化し、パラメーターを受け入れずに文字列を返します.たとえば、ネットワーク問題を表す構造体を定義しましょう.
type networkProblem struct {
    message string
    code int
}
次にerror ()メソッドを定義します:
func (np networkProblem) Error() string {
    return fmt.Sprintf("network error! message: %s, code: %v", np.message, np.code)
}
ここで、エラーを受け入れた場合、ネットワークワーク構造体のインスタンスを使用できます.
func handleErr(err error) {
    fmt.Println(err.Error())
}

np := networkProblem{
    message: "we received a problem",
    code: 404,
}

handleErr(np)

// prints "network error! message: we received a problem, code: 404"

キープインターフェイス


あなたがこの記事から離れているアドバイスの1つの部分があるならば、これを作ってください:小さいインターフェースを保ってください!インターフェイスは、いくつかのエンティティを正確に表現するために必要な最小限の動作を定義するためのものです.
以下に、より大きな動作を定義する良い例が残っている大きなインターフェースの例を示します.
type File interface {
    io.Closer
    io.Reader
    io.Seeker
    Readdir(count int) ([]os.FileInfo, error)
    Stat() (os.FileInfo, error)
}
HTTPファイルhttps://golang.org/pkg/net/http/#pkg-overview
インターフェイスの振る舞いを満たす型はHTTPパッケージでファイルとして考えられます.これはHTTPパッケージがディスク上のファイル、ネットワークバッファ、あるいは単純な[]バイトを扱うかどうかを知る必要がないので便利です.

インターフェイスは、型を満足させる知識がないはずです


インターフェイスは、他の型がそのインターフェイスのメンバーとして分類するために必要なものを定義する必要があります.デザイン時にインタフェースを満たすあらゆるタイプを意識してはいけません.
たとえば、車を定義するのに必要なコンポーネントを記述するインターフェイスを構築しているとしましょう.
type car interface {
    GetColor() string
    GetSpeed() int
    IsFiretruck() bool
}
getcolor ()およびgetspeed ()は完全な意味を持ちます.isfiretrack ()はアンチパターンです.私たちは、すべての車が彼らが消防車であるかどうか宣言するのを強制しています.このパターンが何らかの量の感覚を作るためには、可能なサブタイプのリストを必要とします.isickup ()、issedand ()、iStatk () ......どこで終わりますか?
代わりに、開発者は、type assertionのネイティブの機能に依存している必要がありますときに、車のインターフェイスのインスタンスを与えた場合、基になるタイプを派生させる.あるいは、サブインターフェースが必要なら、以下のように定義することができます.
type firetruck interface {
    car
    HoseLength() int
}
これは、必要なメソッドをcarから継承し、必要なメソッドを一つ追加します.

インターフェースはクラスではない


インターフェースはクラスではありません.
インターフェイスにはコンストラクタまたはそのコンストラクタがありません.
インタフェースは自然によって階層的ではありません、しかし、他のインターフェースのスーパーセットであるように起こるインタフェースをつくるために、構文上の砂糖があります.
インターフェイスは関数シグネチャを定義します.これは、インターフェースを作ることがしばしばstructメソッドに関してコードを乾燥させないことを意味します.つのタイプがエラーインターフェースを満足させるなら、それらはすべて、error ()関数の独自のバージョンを必要とします.

読書ありがとう


あなたが質問やコメントがあればTwitterで私をヒット.
進行中のレーン
Best Practices For Writing Clean Interfaces in Go年には、Qvaultが初めて登場した.