Go 部落格

JSON-RPC:介面的故事

Andrew Gerrand
2010 年 4 月 27 日

在此,我們舉例說明 Go 的 介面 如何輕鬆地重構現有程式碼,使其更具靈活性和可擴充套件性。最初,標準庫的 RPC 包 使用一種稱為 gob 的自定義線上傳輸格式。對於某個特定應用,我們想使用 JSON 作為替代的線上傳輸格式。

我們首先定義了一對介面來描述現有線上傳輸格式的功能,一個用於客戶端,一個用於伺服器(下圖所示)。

type ServerCodec interface {
 ReadRequestHeader(*Request) error
 ReadRequestBody(interface{}) error
 WriteResponse(*Response, interface{}) error
 Close() error
}

在伺服器端,我們將兩個內部函式簽名更改為接受 ServerCodec 介面,而不是我們現有的 gob.Encoder。這是其中一個:

func sendResponse(sending *sync.Mutex, req *Request,
 reply interface{}, enc *gob.Encoder, errmsg string)

變成

func sendResponse(sending *sync.Mutex, req *Request,
  reply interface{}, enc ServerCodec, errmsg string)

然後,我們編寫了一個簡單的 gobServerCodec 包裝器來重現原始功能。從那裡,構建一個 jsonServerCodec 也很容易。

在對客戶端進行了一些類似的更改後,這就是我們對 RPC 包所需要做的全部工作。整個過程大約花了 20 分鐘!在整理和測試新程式碼後,最終的更改集 已被提交。

在像 Java 或 C++ 這樣的面向繼承的語言中,顯而易見的方法是泛化 RPC 類,並建立 JsonRPC 和 GobRPC 子類。然而,如果您想在與該層次結構正交的方向上進行進一步的泛化,這種方法會變得棘手。(例如,如果您要實現一個替代的 RPC 標準)。在我們的 Go 包中,我們採取了一條在概念上更簡單且需要編寫或更改的程式碼量更少的路線。

任何程式碼庫的一個重要品質是可維護性。隨著需求的不斷變化,能夠輕鬆、乾淨地適應程式碼至關重要,否則程式碼將變得難以處理。我們相信 Go 輕量級、面向組合的型別系統提供了一種可擴充套件的程式碼結構。

下一篇文章:新的講座和教程
上一篇文章:第三方庫:goprotobuf 及其他
部落格索引