0時に寝て6時に起きた。2時と3時ぐらいに起きたけど、まぁまぁ眠れた。
go の interface の考え方
メンバーと設計の議論をしていて interface の考え方の概念を誤解しているように感じたので Go Code Review Comments の interfaces で書いてあることの意図や背景などを解説した。メンバー全員を集めて30分ほどで説明した。既存のコードは過剰に interface を設計していて、特定のメソッドを呼び出すラッパー関数を設けて、そのシグネチャに interface を受け取って構造体のメソッドを呼び出すコードを書いている。こんな感じのコード。
type myBehavior interface {
doSome(data string) error
}
type myObject struct {
myBehavior
}
func (o *myObject) doSome(data string) {
...
}
func handleSome(o myBehavior, data string) error
return o.doSome(data)
}
handleSome のようなラッパー関数は不要だし、myObject の構造体に interface を埋め込む必要はないし、Go Code Review Comments では構造体を定義しているところで interface を提供しない方が保守コストが下がってよいよと提案している。これは java のような nominal subtyping と go の structural subtyping の違いで go らしい interface は構造体の提供側ではなく、呼び出し側で勝手に定義して任意の振る舞いを強制できるといった内容を java と go のコードを比較しながら説明した。そして、この話しが重要になるのはサードパーティのライブラリを利用するときに interface が変わると、それを使っている開発者に大きな影響を与えるので interface を提供するなら慎重に練ったものを公開しないといけないという java 開発から得られた知見などが影響しているのではないかという私見も話した。さらに自分たちが管理しているコードなら interface が変わろうが struct のメソッドが変わろうが、すべて自分たちが変更できる権限をもっているから設計時に厳密に interface やメソッドの振る舞いを詰めきれなかったとしても、後から必要ならいつでもいくらでも変えればいいだけと一緒に話した。開発のバランス感覚は経験からでないと身に付かないものだと思う。