前段时间,EA公司开源了红警1的部分代码,大家都在赞叹其代码规范性。周末闲来无事,正好可以欣赏一下所谓“秀色可餐”的代码到底长啥样。
红警1是一款1995年发售的游戏,也就是说,这些代码距今已经25年了。游戏代码是用C++写的,而且现如今C++依然是TIOBE排行榜前五名中的常客,这不仅让人感叹c++这门语言的生命力。
好了,闲话少叙,咱们马上进入正题。首先从github上clone下红警1的代码,打开代码目录,是下面这样式的:
嗯,文件名都是大写,还挺另类的,至少我没有见过其他的C++项目是这样文件命名的。
我们选择其中一个文件,看看它们到底有何特殊之处。好的,就选这个“CONNECT.CPP”和“CONNECT.H”来一探究竟。
首先,从名字来看,这两个文件的代码应该是负责连接功能,但具体是什么类型的连接,谁连接谁,还不得而知。
打开CONNECT.H,映入眼帘的是copyright声明,没啥毛病。
继续往下浏览,是文件的作者,日期和功能说明,非常的规整。
功能说明部分比较长,大概有60行。这么长的文件功能说明倒是比较少见。
通读说明部分,可以得知该文件实现了如下功能:
可以看到,把功能说明部分读了一遍,差不多对该文件的设计意图,实现内容,注意事项全部都清楚了,注意,这时候我还一行代码没有看。
我认为这部分的注释是非常值得我们借鉴的,不用费力去看源码就知道了整体逻辑,非常的省时省力。我想如果你在你的代码中加入这部分注释,后续维护你代码的人会对你感激涕零。
只看我的文字你们还感受不到代码结构的赏心悦目,我整理了下头文件的模板,你们感受一下:
//
// Copyright xxxxxx.
// .....
//
上面这行是指这个文件从反恐精英里copy的吗,擦
#ifndef CONNECTION_H
#define CONNECTION_H
#include "combuf.h"
#define CONN_DEBUG 0
class ConnectionClass
{
public:
ConnectionClass (......);
virtual ~ConnectionClass ();
virtual void Init (void);
xxxxxx
protected:
......
};
#endif
下面继续浏览CONNETC.CPP的代码,文件开头的声明和CONNETC.H的一样,并且列出了当前文件所有的函数:
每一个函数和方法都有固定结构的说明注释,这个结构目前的很多开源代码都在用,而且有文档生成工具,比如doxgen,可以非常方便的从注释生成说明文档。建议大家也采用这样的结构注释,下面是ConnectionClass类的构造函数的说明注释:
方法实现的几乎每行都有注释,而且注释比代码还多。我觉得这部分做的有点过了,有些简单的赋值一眼就能看出意图的没必要添加注释,我猜红警代码的提交检查里应该有注释量/代码量的限制。
通读了整个文件,绝大部分函数都在50行以内,这还包括了空行和注释。函数名定义也非常清晰,知名达意。
说实话,读这些代码让我有种读SQL的感觉,这些代码都是用清晰的函数和变量名,以及间接的逻辑在告诉别的程序员自己在做什么,而不是在堆砌逻辑,只告诉机器该做什么。我想这也是区分优秀程序员和一般程序员的一个标准,优秀程序员是面向程序员,而一般程序员则是面向机器。
总结
最后,来总结下红警代码的优秀风格:
- 清晰的代码注释:注释完整且有统一的结构,极大节省了维护者的阅读成本;
- 声明式编码:以类SQL的方式,声明要做什么,而不是堆砌怎么做;
- 小而精的函数实现:函数只做一件事,并控制函数长度;
我已经打算采用这些风格了,你心动了吗?