(译)我的codereview习惯 的清单

翻译自
https://medium.com/@catalinaturlea/how-i-do-code-review-caa0e5828d8e

作者 Catalina Turlea

我的codereview习惯 的清单

就像我上篇文章写的那样,我真的相信 code reviews 是一个非常有价值的习惯。

我是从一个非常有才华并且也很严厉的开发者那里学习了一些关于code reviews的工作。开始总是困难的,但是它总是在我意想不到的地方帮我提高自己的能力。

至那以后,我花费了一些时间和精力去进行适当的 reviews。我的同事都知道,在进行reviews的时候,我是最容易激动的人,而且在那个时候,我也会很严厉。

以我的经验来说,同样的事情,总是会反复又反复,所以我学会总结这类事情。我是一个iOS 开发者,所以我想到的大多和iOS平台相关。

但是我认为,不论是哪种开发语言,这些东西应该是相通的。

下面的代码段是基于Swift和Objective-C的,但是我希望对于其他语言的开发者来说也同样清晰。So,让我们开始review 代码吧。

Language independent red flags

1、Don’t repeat yourself -DRY (不要重复)

类似下面的代码

// 检测 数组是否为空
if array.count == 1 {
   submitFormWithValues("Only one value selected", array)
} else {
   submitFormWithValues("\(array.count) values selected", array)
}

第一眼看上去好像没什么问题,但是如果你仔细看,你会发现,这个方法会调用两次。即使他只有一个判断条件。
假如,举个例子,这个方法如果被重命名,或者添加第三个参数,你需要在两个位置修改代码,因为这个是你代码中的重复部分。

下面的代码就会很好的避免这个问题

let string = array.count == 1 ? "Only one value selected" : "\(array.count) values selected"
// 现在我们就只会调用一次这个方法了
submitFormWithValues(string, array)

现在,如果你要袖肥这个方法的话,你只需要修改一个地方就可以了,在也不需要重复了。

这还有很多类似的例子。当你在一个方法或者一个文件中看到类似的代码时,你需要问问自己,为什么不把重复的代码删掉?

2、Returning booleans


func isEmpty(array: [String]) -> Bool {
   if array.count == 0 {
       return true
   } else {
       return false
   }
}

每当你返回一个布尔值前,你应该仔细看下你的代码,因为大多数情况下,你都可以用一种更简单的写法

func isEmpty(array: [String]) -> Bool {
   return array.count == 0
}

这种写法同样适用于 计算对象的布尔属性。就像这样:

func hideHeaderIfEmptyTableView() {
   if datasource.count == 0 {
       header.hidden = true
   } else {
       header.hidden = false
   }
}

这是非常相似的例子,当你赋值布尔属性或者返回布尔属性的时候,你可以使用下面的这种更直接的写法


func hideHeaderIfEmptyTableView() {
   header.hidden = (datasource.count == 0)
}

3、Reduce the level of indentation and use early exits

在你的代码中嵌套的层级越多,代码越难被阅读和理解。我们的大脑一次只能处理有限的状况,所以,越多的循环,就会让我们的大脑越有负担。

我们不应该将所有的包含在一个if循环中,你只需要添加一个不循环的条件在前面,并且return

所以,这是一个比较直接的途径,而不是想下面这样:

func myMethod(elements: [String]) {
   if elements.count > 0 {
      for element in elements {
        // do some processing
      }
   }
}

你应该使用:

func myMethod(elements: [String]) {
   if elements.isEmpty {
      return
   }
   for element in elements {
      // do some processing
   }
}

我也意识到它可能只是代码风格的问题,但是我认为这样做更容易去遵守,并且让控制流更加的线性。

4、“Shy” code

就像The Pragmatic Programmer中提到的那样,你的代码应该永远是“shy code”。
尽量在最小范围内写每件事,只有在你真的需要的时候增加这个范围。
举个例子,从所有事情** **私有开始,包括你的属性和方法。

我认为这同样适用于属性的暴露级别,假如你有一个内部包含一个图片的自定义UI组件,同时它需要在外部设置,你可以提供一个更新它的方法,而不是将它作为一个可读写的属性。这样iamge就会作为一个只读的存在,并且你也可以在你属性的值上有更多的限制。

5、Remove empty methods and any unused generated code


The best code is the one that does not exist

要养成将不用的代码删除的习惯(哪怕是IDE自动生成的)。不要让你的代码中包含空方法,未用的变量,导入,无效的注释。如果你不需要它,那就删掉它。

删除代码应该是开发者最喜欢的活动之一。

一些其他的建议

当你review代码时,你应该牢牢的记住这些:

  • Hard-coded values:首先,你应该问自己,没有方法去替代这个静态值么?如果有,那么让它变得更好,如果没有,那就将它存储在静态变量中。这些值的命名应该和上下文有所联系,比如imageDefaultWidth 或者 controllerIdentifier,在有利于在一段时间后,容易理解这些值的意思。这样做的另一个好处是,这些值会在不同的地方重复出现。如果没有将它存在变量中,那么当你要做出改变的时候,比如将值从3修改为4,那么你将要在任何需要改变的地方做出修改。
    建立团队标准和准则 - 确定标准,并且每个人都要遵守,不要在
    code review*时忽略这点。它应该包括变量的命名规则,代码规范,团队公认的开发语言好的尝试。

  • Log your errors - 或许这点是显而易见的,但是我还是认为,它值得提起。确保每次你的代码出现问题时都能及时记录,哪怕你认为它不可能发生,记下这个错误尽可能多的信息,它非常有用。

Objetive-c / swift specific observations

1、确保已经注销了观察者

每次review或者编写有关于注册某种通知或者订阅时,你都应该确认你是否注销或者取消订阅了。如果你忽略了这点,我相信你会知道“Message sent to deallocated instance”有多难debug

我十分强调这一点,check,check,check。

2、Most specific method arguments

举个例子,button callbacks。应当为方法参数添加最详细的类型和调用对象。

好处体现在两个地方:一旦它更清晰,那么只会有一个button能调用这个方法,你不需要去检查对象的属性,不用描述它或者任何事情。你也许现在不需要,但是你需要为将来的开发流出空间。

@IBAction func didClickContinue(sender: id) { 
   // 一年后,估计你就记不起调用这个方法的是哪种类型的对象了
}

你应该用一些更加有意义的描述去快速的指出这段代码的实际用途

// 怎样使用这个方法?你会知道这个方法怎样用,也会知道哪个对象对调用这个方法
@IBAction func didClickContinueButton(sender: UIButton) {
}

关于方法:

// 永远都要将调用对象包含在callback中
let tapGesture = UITapGestureRecognizer(target: self, action: “didTap:”)

3、Most generic object references

当你使用一个对象时,尽可能的将它存在最通用的类型中,这不影响你使用你需要的功能

例如:

private var viewController: AlertViewController?
init() {
   viewController = AlertViewController()
   navigationController?.pushViewController(viewController,     animated: true)
}

你需要注意的是,push方法只需要一个UIViewController而不是一个AlertViewController,所以你应该将它存在一个最通用的类型中比如UIViewController

// 我们不需要AlertViewController的特殊属性,所以,我们将它存为*UIViewController*
private var viewController: UIViewController?
init() {
   viewController = AlertViewController()
   navigationController?.pushViewController(viewController, animated: true)
}

这里的想法是,不要在没有给出具体需求的时候,给出信息。* *对象之间联系越少,依赖就越小。

4、Documentation - Pargma marks

当一个类变得越来越大的时候(无论多么优秀的开发者,都会出现这样的问题),为public/private methods, the protocol implementations, public/private variables做一些限定,对于我们理解和工作都是非常有用的。

Other things to keep an eye for

  • 循环引用 - 保证delegate是弱引用。同样在blocks中保证self weak,去避免循环引用。
  • 不必要的代码 - 就像前面提到的,不要在你的代码中包含无用的代码。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,792评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • error code(错误代码)=0是操作成功完成。error code(错误代码)=1是功能错误。error c...
    Heikki_阅读 3,368评论 1 9
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62