离开 Java 的 101 天,关于继承

mmf多多 · · 979 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

程序设计一个很重要的优化点是减少重复代码。一件完成了的事情没人愿意做多次,一堆代码没人愿意重复写好几遍,哪怕是复制粘贴。


但当接触的 Golang 代码多了,渐渐的需要用 Golang 写一些有用的项目,发现有时候极难复用已有的代码。思来想去,一个号称具备生产力的语言怎能容忍弱鸡的复用代码的能力。

下面举个例子:

图片发自简书App

这个片断企图改写 http 包 Client 结构的方法以达到传递 context 的效果。因发起 HTTP 请求的各大方法都通过调用 Do 方法来执行请求,常规思维下,只需新声明一个结构继承 Client 然后重写 Do 方法就行了。

于是就可以通过下面代码中的方式传递自定义的 context :

图片发自简书App

曾经的 Java 经验,让我会觉得这是很自然的一种写法。

在刚接触 Golang 语言时,通过各种途径发现的事实是它不是面向对象的语言,它没有继承,也没有方法重写。多年代码设计的经验告诉我,当一种模式缺失时,它一定会以另一种形式出现,从逻辑上来看它们应该等价。

后来得知了一个概念:Embedding。即,可以在 Golang 的 struct 或 interface 中嵌入其他的 struct 或 interface。表现出来的效果就像是继承。于是就有了上面例子的写法。

当时写这段代码的时候非常希望能按预期工作。直接复用标准库中的代码,只用改写应该改写的代码,看起来也是优雅的,没有堆砌感。

可遗憾的是并不能按预想的方式运行,context 并不会传递下去,也就是 req 的 ctx 值并不会被替换掉。Golang 没有继承。于是不得不妥协采用其他常规的方式来实现。如下:

图片发自简书App

因重复的部分有点多,所以这个版本只实现了 GET、 HEAD 和 POST 这三个方法,其他的直接调用 Do。为了传递 context 不得不重复写所有的方法,写起来真的是特别累。

通过上面的改写,在使用的时候就是下面这个样子:

图片发自简书App

Get 的第一个参数传递 context ,应该是很熟悉的写法。

Golang 另一种避免重复写大量代码的方式是用工具生成代码。偶尔也会用到这个方法。但这其实是另一个维度的概念了。


图片发自简书App

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:mmf多多

查看原文:离开 Java 的 101 天,关于继承

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

979 次点击  
加入收藏 微博
1 回复  |  直到 2019-06-11 10:52:18
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传