关于编程风格与代码可读性(1)

来源:互联网 发布:交友软件排名 编辑:程序博客网 时间:2024/06/14 12:42

常言道:“字如其人”。对于程序员来说,代码就是他们的著作。好的编程风格是成为一个好的程序员的必要条件。

编程风格是一个程序员在写代码时的一些惯例。好的编程风格,与代码的可读性有着不可分割的关系。好的编程风格,并不是个性的写法,而是大多程序员都共同认可的、可读性强的习惯性代码写法。

本文主要总结《The Art of Readable Code》一书,来说明编程风格与代码可读性的问题。(The Art of Readable Code by Dustin Boswell and Trevor Foucher. Copyright 2012 Dustin Boswell and Trevor Foucher, 978-0-596-80229-5)。

优秀编程风格的原则:代码应该易于理解。阅读代码的人是否能快速的读懂你的代码(Time-Till-Understanding),是编程风格好坏的关键。

基础层面的改进

一、关于命名

(1)选用特定的单词

例:

class BinaryTree {int Size();...};
上面代码中,Size() 的返回值是这个二叉树的节点数能,还是二叉树的高度?如果将Size()替换成NumNodes()或Height(),则能直接传递更多的信息。


(2)避免一般的命名

①tmp :temporary一般用于存放临时变量。

当变量tmp的生命周期只有几行代码时,使用tmp是一个很好的选择。例:

if (right < left) {tmp = right;right = left;left = tmp;}
而当tmp在函数直接传递,或者需要被修改和多次使用时,使用tmp作为变量名是一个偷懒的行为。例:

string tmp = user.name();tmp += " " + user.phone_number();tmp +- " " + user.email();...template.set("user_info", tmp);

在上面代码中,tmp改为user_info则能更好的描述变量本身。

②retval : return value。一般用于存放返回值。 当你使用retval时,就在向阅读代码的人说,我想不到名字。例:

var euclidean_norm = function (v) {var retval = 0.0;for (var i = 0; i < v.length; i += 1)retval += v[i] * v[i];return Math.sqrt(retval);};

在上面代码中,retval改为sum_squeares则更佳。

③Loop Iterators(i, j, iter)。i,j,k,iter为常用的迭代器名。例:

for (int i = 0; i < club.size(); i++)for (int j = 0; j < club[i].members.size(); j++)for (int k = 0; k < users.size(); k++)if (clubs[i].member[k] == users[j])cout << "user[" << j << "] is in club[" << i << "]" << endl;

如果细心的话,就会发现if (clubs[i].member[k] == users[j]) 这句的迭代器写错了。如果将(i, j, k)改成(ci, ui, mi),则判断语句为if (clubs[ci].member[ui] == users[mi]) 可以明显看出迭代器使用的错误。


(3)用具体的变量名替换抽象的变量名

例如:void CleanRepley(),从函数名中我们只能知道函数的作用是对Repley进行一些整理,但具体的工作我们并不了解。如果将变量名改为 void DeleteReply(),则可以清晰的知道,函数的作用为删除回复。


(4)在变量名中附加信息

①在变量名里加上单位。例:

var start = (new Date()).getTime(); // top of the page...var elapsed = (new Date()).getTime() - start; // bottom of the pagedocument.writeln("Load time was: " + elapsed + "seconds")
上述代码中,没有明显错误。但是getTime() 的返回值的单位为ms,而不是s。为了使表达更清晰,我们可以将start与elapsed加上单位在后面,代码更改如下:

var start_ms = (new Date()).getTime(); // top of the page...var elapsed_ms = (new Date()).getTime() - start_ms; // bottom of the pagedocument.writeln("Load time was: " + elapsed_ms + "seconds")
②在变量名里加上特征。例:
如果是以明文保存的password,可改变量名为plaintext_password。


(5)变量名的长度问题

变量名长短的限制,要根据具体使用情况分析。

①作用于小范围内(在代码中出现的行数)的变量可以简短。 例:

if (debug) {map<string, int> m;LookUpNamesNumbers(&m);Print(m);}
虽然变量名 m 没有携带太多信息,但是它已经拥有了它所要所有信息。然而,在全局变量中使用m ,则不妥。如下例:

LookUpNamesNumbers(&m);Print(m);
②对于长的变量名,现在的编译器大都有自动补全功能。所以,输入长的变量名,不再是一个烦人的问题。
③单词缩写的使用。

在命名中,我们常常使用单词的缩写。将FormatString()缩写为FormatStr(),我们也可以很清楚明白意思。然而,将BackEndManager缩写为BEManager,我们就很难明白。所以在命名的缩写中,我们要注意惯用的缩写。

④扔到没有的单词

例如:ConvertToString()可以简化为ToString(),DoServeLoop()可以简化为ServeLoop()。


(6)形成一些惯例

例如,通过 _ 和 - 的不同来区分变量特征。<div id="middle_column" class="main-content">。





The Art of Readable Code by Dustin Boswell and Trevor Foucher. Copyright 2012 Dustin Boswell and Trevor Foucher, 978-0-596-80229-5