同樣都是使用介面,JAVA 和 Go 差距咋就這麼大呢?
這篇文章將描述程式碼中經常使用的搶佔式介面模式,以及為什麼我認為在 Go 中遵循這種模式通常是不正確的。
什麼是搶佔式介面
介面是一種描述行為的方式,存在於大多數型別語言中。搶佔式介面是指開發人員在實際需要出現之前對介面進行編碼。一個示例可能如下所示。
type Auth interface {
GetUser() (User, error)
}
type authImpl struct {
// ...
}
func NewAuth() Auth {
return &authImpl
}
搶佔式介面何時有用
搶佔介面通常用於在 Java 中,並且大獲成功,這是大部分程式設計師的想法。相信,很多 Go 開發者也是這麼認為的。這種用法主要區別在於 Java 具有顯式介面,而 Go 是隱式介面。讓我們看一些示例 Java 程式碼,這些程式碼顯示瞭如果不使用 Java 中的搶佔式介面可能會出現的困難。
// auth.java
public class Auth {
public boolean canAction() {
// ...
}
}
// logic.java
public class Logic {
public void takeAction(Auth a) {
// ...
}
}
現在假設您要更改 Logic 的 takeAction 方法中的引數 Auth 型別的物件,只要它具有 canAction() 方法即可。不幸的是,你不能。Auth 沒有在其中實現帶有 canAction() 的介面。你現在必須修改 Auth 為其提供一個介面,然後您可以在 takeAction 中接受該介面,或者將 Auth 包裝在一個除了實現的方法之外什麼都不做的類中。即使 logic.java 定義了一個 Auth 介面以在 takeAction() 中接受,也可能很難讓 Auth 實現該介面。您可能無權修改 Auth,或者 Auth 可能位於第三方庫中。也許 Auth 的作者不同意你的修改。也許在程式碼庫中與同事共享 Auth,現在需要在修改之前達成共識。這是希望的 Java 程式碼。
// auth.java
public interface Auth {
public boolean canAction()
}
// authimpl.java
class AuthImpl implements Auth {
}
// logic.java
public class Logic {
public void takeAction(Auth a) {
// ...
}
}
如果 Auth 的作者最初編碼並返回一個介面,那麼你在嘗試擴充套件 takeAction 時,永遠不會遇到問題。它自然適用於任何 Auth 介面。在具有顯式介面的語言中,以後你會感謝過去的自己使用了搶佔式介面。
為什麼這在 Go 中不是問題
讓我們在 Go 中設定相同的情況。
// auth.go
type Auth struct {
// ...
}
// logic.go
func TakeAction(a *Auth) {
// ...
}
如果 logic 想要使 TakeAction 通用,則 logic 所有者可以單方面執行此操作,而不會打擾其他人。
// logic.go
type LogicAuth interface {
CanAction() bool
}
func TakeAction(a LogicAuth) {
// ...
}
請注意 auth.go 不需要更改。這是使搶佔式介面不再需要的關鍵所在。
Go 中搶佔式介面的意外副作用
Go 的介面定義都是很小,但很強大。在標準庫中,大多數介面定義都是單一方法。這允許最大的重用,因為實現介面很容易。當程式設計師對像上面的 Auth 這樣的搶佔式介面進行編碼時,介面的方法數量往往會激增,這使得介面(可交換實現)的全部意義更難以實現。
Go 中介面的最佳用法
Go 的一個很好的經驗法則是 - 接受介面,返回結構體。接受介面為您的 API 提供了最大的靈活性,返回結構體允許呼叫者快速導航到正確的函式。
即使你的 Go 程式碼接受結構體並返回結構體以啟動,隱式介面也允許您稍後擴充套件你的 API,而不會破壞向後相容性。介面是一種抽象,抽象有時很有用。然而,不必要的抽象會造成不必要的複雜化。在需要之前不要使程式碼過於複雜。
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 都是《賽博朋克2077》,為什麼差距就這麼大
- 咋就這麼不喜歡手寫路由呢路由
- 朋友工作兩年,月薪20k,同樣是程式設計師差距怎麼這麼大?程式設計師
- 通用的 Java 介面白盒測試,大家都是怎麼進行的呢?Java
- 同樣的SQL,怎麼突然就慢了?SQL
- 同樣都是燉大白菜視訊,一個播放量幾百,一個幾十萬,差距在哪?
- hadoop,spark,Zookeeper,,, 這些名字都是怎麼來的呢?HadoopSpark
- 同樣做前端,為何差距越來越大?前端
- 組態軟體特徵分析!同樣都是拖拉拽,為什麼別人的頁面這麼好看?特徵
- 同樣是持久化,竟然有這麼大的差別!持久化
- 各位大專生們工作咋樣?
- 學Java怎麼樣?學Java從業前景如何呢?Java
- 月薪5萬和5000之間的差距,就是這樣拉開的
- SpringBoot中如何使用ObjectMapper,老鳥們都是這樣玩的?Spring BootObjectAPP
- Java就業前景怎麼樣?值得學嗎?Java就業
- Java3大框架的學習都是什麼Java框架
- 遊戲和CG裡的人物,都是怎麼動起來的呢?遊戲
- 同樣都是打工人,為何別人會大資料建模,而你只會用EXCEL?大資料Excel
- 這屆CSS大會都有誰?他們會和大家聊什麼呢?CSS
- 同樣都是“遊戲盒子” 為什麼Roblox在iOS平臺不受限制?遊戲iOS
- 學Java需要什麼技巧呢?分享這4個Java
- 大資料就業前景好嗎 鄭州大資料就業怎麼樣大資料就業
- 網路直播亂象咋這麼“頑強”?
- 同樣都是調參,為什麼人家的神經網路比我牛逼100倍?神經網路
- 2014年IT行業薪資調查 嚇哭了~原來差距這麼大!行業
- 學習linux前景咋樣Linux
- 在 Go 語言中,我為什麼使用介面Go
- 青黃不接成定局,超休閒遊戲的翻身仗咋就這麼難打?遊戲
- Springboot 日誌、配置檔案、介面資料如何脫敏?老鳥們都是這樣玩的!Spring Boot
- Java的3大框架都學習什麼呢?Java框架
- Java實現一個棧就這麼簡單Java
- MYSQL 使用基礎 - 這麼用就對了MySql
- 測試支付介面怎麼處理支付成功這種場景呢?
- 同樣是電晶體,為什麼暫存器比記憶體快呢?記憶體
- 8年Java面試官:月薪8000和30000的差距是什麼?Java面試
- Java列舉類,這樣使用優雅、易懂Java
- 學習Java以後的就業形勢怎麼樣?Java就業
- DevOps升級&AIOps落地,看看這些大廠都是怎麼做的?devAI