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 及更多
博客索引