欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

欣赏一下“秀色可餐”的代码

程序员文章站 2022-04-25 21:19:18
...

前段时间,EA公司开源了红警1的部分代码,大家都在赞叹其代码规范性。周末闲来无事,正好可以欣赏一下所谓“秀色可餐”的代码到底长啥样。

红警1是一款1995年发售的游戏,也就是说,这些代码距今已经25年了。游戏代码是用C++写的,而且现如今C++依然是TIOBE排行榜前五名中的常客,这不仅让人感叹c++这门语言的生命力。

好了,闲话少叙,咱们马上进入正题。首先从github上clone下红警1的代码,打开代码目录,是下面这样式的:
欣赏一下“秀色可餐”的代码
嗯,文件名都是大写,还挺另类的,至少我没有见过其他的C++项目是这样文件命名的。

我们选择其中一个文件,看看它们到底有何特殊之处。好的,就选这个“CONNECT.CPP”和“CONNECT.H”来一探究竟。

首先,从名字来看,这两个文件的代码应该是负责连接功能,但具体是什么类型的连接,谁连接谁,还不得而知。

打开CONNECT.H,映入眼帘的是copyright声明,没啥毛病。

继续往下浏览,是文件的作者,日期和功能说明,非常的规整。

功能说明部分比较长,大概有60行。这么长的文件功能说明倒是比较少见。
通读说明部分,可以得知该文件实现了如下功能:
欣赏一下“秀色可餐”的代码
可以看到,把功能说明部分读了一遍,差不多对该文件的设计意图,实现内容,注意事项全部都清楚了,注意,这时候我还一行代码没有看。

我认为这部分的注释是非常值得我们借鉴的,不用费力去看源码就知道了整体逻辑,非常的省时省力。我想如果你在你的代码中加入这部分注释,后续维护你代码的人会对你感激涕零。

只看我的文字你们还感受不到代码结构的赏心悦目,我整理了下头文件的模板,你们感受一下:

//
// Copyright xxxxxx.
// .....
//
/* $Header: /CounterStrike/CONNECT.H 1     3/03/97 10:24a Joe_bostic $ */
上面这行是指这个文件从反恐精英里copy的吗,擦
/***************************************************************************
 **   C O N F I D E N T I A L --- W E S T W O O D    S T U D I O S        **
 ***************************************************************************
 *                                                                         *
 *                 Project Name : Command & Conquer                        *
 *                                                                         *
 *                    File Name : CONNECT.H                                *
 *                                                                         *
 *                   Programmer : Bill Randolph                            *
 *                                                                         *
 *                   Start Date : December 19, 1994                        *
 *                                                                         *
 *                  Last Update : April 1, 1995   [BR]                 	*
 *                                                                         *
 *-------------------------------------------------------------------------*
 *                                                                         *
 * DESCRIPTION:             						*
 * This class represents a single "connection" with another system.  It's	*
 * a pure virtual base class that acts as a framework for other classes.	*
 *										*
 * ......									*
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CONNECTION_H
#define CONNECTION_H

/*
********************************* Includes **********************************
*/
#include "combuf.h"

/*
********************************** Defines **********************************
*/
#define CONN_DEBUG	0

/*
***************************** Class Declaration *****************************
*/
class ConnectionClass
{
	/*
	---------------------------- Public Interface ----------------------------
	*/
	public:
		/*.....................................................................
		Constructor/destructor.
		.....................................................................*/
		ConnectionClass (......);
		virtual ~ConnectionClass ();

		/*.....................................................................
		Initialization.
		.....................................................................*/
		virtual void Init (void);

		/*.....................................................................
		Send/Receive routines.
		.....................................................................*/
		xxxxxx

	/*
	-------------------------- Protected Interface ---------------------------
	*/
	protected:
		......
};

#endif

/**************************** end of connect.h *****************************/

下面继续浏览CONNETC.CPP的代码,文件开头的声明和CONNETC.H的一样,并且列出了当前文件所有的函数:

/*-------------------------------------------------------------------------*
 * Functions:    			                                       *
 *   ConnectionClass::ConnectionClass -- class constructor                 *
 *   ConnectionClass::~ConnectionClass -- class destructor                 *
 *   ConnectionClass::Init -- Initializes connection queue to empty	       *
 *   ......                                                                *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

每一个函数和方法都有固定结构的说明注释,这个结构目前的很多开源代码都在用,而且有文档生成工具,比如doxgen,可以非常方便的从注释生成说明文档。建议大家也采用这样的结构注释,下面是ConnectionClass类的构造函数的说明注释:

/***************************************************************************
 * ConnectionClass::ConnectionClass -- class constructor                   *
 *                                                                         *
 * INPUT:                                                                  *
 *		numsend			desired # of entries for the send queue					*
 *		numreceive		desired # of entries for the receive queue				*
 *		maxlen			max length of an application packet					*
 *		magicnum			the packet "magic number" for this connection			*
 *		retry_delta		the time to wait between sends						*
 *		max_retries		the max # of retries allowed for a packet				*
 *							(-1 means retry forever, based on this parameter)	*
 *		timeout			the max amount of time before we give up on a packet	*
 *							(-1 means retry forever, based on this parameter)	*
 *		extralen			max size of app-specific extra bytes (optional)			*
 *                                                                         *
 * OUTPUT:                                                                 *
 *		none.								*
 *                                                                         *
 * WARNINGS:                                                               *
 *		none.								*
 *                                                                         *
 * HISTORY:                                                                *
 *   12/20/1994 BR : Created.                                              *
 *=========================================================================*/

方法实现的几乎每行都有注释,而且注释比代码还多。我觉得这部分做的有点过了,有些简单的赋值一眼就能看出意图的没必要添加注释,我猜红警代码的提交检查里应该有注释量/代码量的限制。

通读了整个文件,绝大部分函数都在50行以内,这还包括了空行和注释。函数名定义也非常清晰,知名达意。

说实话,读这些代码让我有种读SQL的感觉,这些代码都是用清晰的函数和变量名,以及间接的逻辑在告诉别的程序员自己在做什么,而不是在堆砌逻辑,只告诉机器该做什么。我想这也是区分优秀程序员和一般程序员的一个标准,优秀程序员是面向程序员,而一般程序员则是面向机器。

总结

最后,来总结下红警代码的优秀风格:

  • 清晰的代码注释:注释完整且有统一的结构,极大节省了维护者的阅读成本;
  • 声明式编码:以类SQL的方式,声明要做什么,而不是堆砌怎么做;
  • 小而精的函数实现:函数只做一件事,并控制函数长度;

我已经打算采用这些风格了,你心动了吗?