Golang 語言編程使用接口有哪些好處?
01介紹
在 Golang 語言中,接口類型定義了一組方法簽名,接口類型的值可以保存實現(xiàn)了這些方法的任何值。
Golang 語言的接口是隱式實現(xiàn)的,它不像其他某些編程語言,使用 implements 關(guān)鍵字顯式實現(xiàn)接口,Golang 語言沒有 implements 關(guān)鍵字,一個類型只要實現(xiàn)接口定義的所有方法,就等于實現(xiàn)了該接口,所以也稱為 Duck typing。
if something looks like a duck, swims like a duck and quacks like a duck then it’s probably a duck.
關(guān)于 Golang 語言接口的使用,我們已經(jīng)在前面的文章中介紹過,感興趣的讀者朋友可以翻閱一下。本文我們介紹一下使用接口有哪些好處?
02使用接口的好處
在 Golang 語言中,我們使用結(jié)構(gòu)體和方法可以很完美的實現(xiàn)需求。為什么還要使用接口呢?實際上,接口是一個工具,是否選擇使用接口,取決于我們自己,它可以使我們的代碼更優(yōu)雅,更簡潔,更具可讀性。下面我們通過一個簡單示例來說明接口的這些好處。
示例代碼:
- type Cat struct {
- }
- func (c Cat) Say() string {
- return "miaow"
- }
- type Dog struct {
- }
- func (d Dog) Say() string {
- return "woof woof"
- }
- func TestSay(t *testing.T) {
- c := Cat{}
- t.Log("Cat say:", c.Say())
- d := Dog{}
- t.Log("Dog say:", d.Say())
- }
閱讀上面這段代碼,我們定義了兩個結(jié)構(gòu)體 Cat 和 Dog,并分別為其實現(xiàn)了 Say 方法。讀者朋友們是否感覺到代碼有些重復(fù),因為 Cat 和 Dog 都有相同的簽名的方法 Say,所以我們可以使用接口重構(gòu)一下這段代碼。
示例代碼:
- type Sayer interface {
- Say() string
- }
- type Cat struct {
- }
- func (c Cat) Say() string {
- return "miaow"
- }
- type Dog struct {
- }
- func (d Dog) Say() string {
- return "woof woof"
- }
- type Horse struct {
- }
- func (h Horse) Say() string {
- return "neigh"
- }
- func TestSay(t *testing.T) {
- c := Cat{}
- // t.Log("Cat say:", c.Say())
- //
- d := Dog{}
- // t.Log("Dog say:", d.Say())
- h := Horse{}
- animals := []Sayer{c, d, h}
- for _, a := range animals {
- t.Log("say:", a.Say())
- }
- }
閱讀上面這段代碼,我們定義了一個接口 Sayer,該接口只有一個方法簽名 Say。并且我們又新定義了一個結(jié)構(gòu)體 Horse,和未使用接口的代碼不同的是,我們不需要使用 h.Say() 調(diào)用 Horse 結(jié)構(gòu)體的 Say 方法。
03接口編程案例
在 Golang 語言項目開發(fā)中,為了更加方便操作 MySQL,我們通常會選擇開源 ORM,但是社區(qū)有很多 ORM,可能在項目后期會遇到更換 ORM 的需求,我們可以使用接口使 ORM 盡量少的侵入業(yè)務(wù)代碼,為以后替換 ORM 做準(zhǔn)備。
- type DBOrm interface {
- Insert(param ...interface{})
- }
- type XormDB struct {
- db *xorm.Session
- }
- func (x *XormDB) Insert(param ...interface{}) {
- _, err := x.db.Insert(param)
- if err != nil {
- log.Println(err)
- }
- }
- // type GormDB struct {
- // db *gorm.DB
- // }
- //
- // func (g *GormDB) Insert(param ...interface{}) {
- // g.db.Create(param)
- // }
- type User struct {
- orm DBOrm
- Id int64
- Name string
- }
- func (u *User) DB() DBOrm{
- u.orm = new(XormDB) // 數(shù)據(jù)庫實例注入接口
- // u.orm = new(GormDB)
- return u.orm
- }
- func TestOrm(t *testing.T) {
- user1 := new(User)
- user1.Name = "lucy"
- user1.DB().Insert(user1)
- }
閱讀上面這段代碼,我們創(chuàng)建了一個接口 DBOrm,創(chuàng)建了兩個 ORM 結(jié)構(gòu)體,并分別實現(xiàn)了接口 DBOrm 的簽名方法,在業(yè)務(wù)結(jié)構(gòu)體 User 中,包含的不是某個 ORM 結(jié)構(gòu)體,而是 DBOrm 接口。
04總結(jié)
本文我們主要介紹在 Golang 語言項目開發(fā)中,為什么使用接口,以及使用接口的好處,并通過示例代碼證明接口帶來的好處。
最后,通過使用接口調(diào)用 ORM 的案例,介紹在實際項目開發(fā)中,接口為項目開發(fā)帶來的好處。