Golang 面向?qū)ο缶幊?非侵入式接口
在go語言中,一個(gè)類只需要實(shí)現(xiàn)了接口要求的所有函數(shù),我們就說這個(gè)類實(shí)現(xiàn)了該接口,例如:
type File struct {
// ...
}
func (f *File) Read(buf []byte) (n int, err error)
func (f *File) Write(buf []byte) (n int, err error)
func (f *File) Seek(off int64, whence int) (pos int64, err error)
func (f *File) Close() error
這里我們定義了一個(gè)File類,并實(shí)現(xiàn)了Read()、Write()、Seek()、Close()等方法。設(shè)想我們有如下接口:
type IFile interface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
Seek(off int64, whence int) (pos int64, err error)
Close() error
}
type IReader interface {
Read(buf []byte) (n int, err error)
}
type IWriter interface {
Write(buf []byte) (n int, err error)
}
type ICloser interface {
Close() error
}
盡管File類并沒有從這些接口繼承,甚至可以不知道這些接口的存在,但是File類實(shí)現(xiàn)了這些接口,就可以進(jìn)行賦值:
var file1 IFile = new(File)
var file2 IReader = new(File)
var file3 IWriter = new(File)
var file4 ICloser = new(File)
Go語言的非侵入式接口,看似只是做了很小的文法調(diào)整,實(shí)則影響深遠(yuǎn)。
其一,Go語言的標(biāo)準(zhǔn)庫(kù),再也不需要繪制類庫(kù)的繼承樹圖,在Go中,類的繼承樹并無意義,你只需要知道這個(gè)類實(shí)現(xiàn)了哪些方法,每個(gè)方法是什么含義就足夠了。
其二,實(shí)現(xiàn)類的時(shí)候,只需要關(guān)心自己應(yīng)該提供哪些方法,不用再糾結(jié)接口需要拆的多細(xì)才合理。接口由使用方按需定制,而不用事先規(guī)劃。
其三,不用為了實(shí)現(xiàn)一個(gè)接口而導(dǎo)入一個(gè)包,因?yàn)槎嘁胍粋€(gè)外部包,就意味著更多的耦合。接口按使用方按自身需求來定義,使用方無需關(guān)心是否有其他模塊定義過類似的接口。