我的程序风格
//------------------------------
//create time: 2005-12-21
//creater:小鱼,liang_0735@21cn.com,www.mwjx.com
//purpose:总结归纳经验,与其它程序员交流
//------------------------------
程序的风格,我会时时改变它,这个没有对错,只有习惯与否,你觉得习惯,并能提高效率,那对你就是个好风格。
基本准则,不求完美,当前80分即可。
简单是美,朴素是美,华丽的美对程序员很奢侈。

1,花括号位置
2,函数返回值
3,函数说明
4,什么时候都进行有效性检查吗?
5,大小写

未完待续
1,花括号位置
我经历了4种变化。
最开始毫无规律,然后规定自己所有花括号都另起一行,像这样:
if(true)
{
}
else
{
}
比较傻,当初不知看了哪本书,说是else后面即使没有内容也加一对空括号,这样有利于以后修改程序,你看以后不用写花括号就可在else后面写东西了。
再然后决定把前面的花括号收到语句的行末,比如:
if(true){
}
这样可以节省一行空间,当然函数的花括号还是另起一行。
直到现在,我用起了以前觉得很不顺眼的方式,就是花括号能不写就不写,这样能节省更多的行数:
if(true)
	do it;
else
	not do it;
2,函数返回值
我以前特喜欢在函数后面返回一个布尔值,无论什么函数,我都返回它,true成功,flase失败。
一般一个错误从最里面到最外层要经过5,6层,多的达到十几二十层,查找原因当然很麻烦,往往一个小问题,从最外层查起,要查半个小时甚至更多。
像这样:
show_name()
{
	if(!get_name())
		return false;
	if(!show(get_name()))
		return false;
	return true;
}
这个show_name函数如果返回false,要查它原因,我得找get_name和show这两个函数,而这两个函数可能又有各自的委托对象,我得把这些被委托对象挨个查,谁知道这些被委托对象又会依赖谁?
到现在我认识到虽然每个函数都返回成功状态都有效控制程序质量,但实在是个累人的方法,应该收缩它的使用范围。
现在我开始喜欢这样的声明:
void show_name() const;
如果重要的地方,我可能会先检查它的条件是否满足:
if(name_ok())
	show_name();
而以前我习惯:
if(!show_name())
	show("why?????");
3,函数说明
void function show_name(const user *aman)
{
	//显示玩家用户名
	//输入:aman是玩家对象指针
	//输出:无
	show(aman->get_name());
}
4,什么时候都进行有效性检查吗?
本着错误越早发现越好,不要做任何假设的原则,我的函数在处理前一般进行大量有效检查。如:
show_name(const user *aman)
{
	//检查显示系统是否正常,下面的show函数就是本系统的方法
	if(!check_system_show())
		return false;
	//检查要操作的用户对象是否正常,下面的get_name就是本对象的方法
	if(!user_right(aman))
		return false;
	if(!aman->get_name())
		return false;
	if(!show(aman->get_name()))
		return false;
	return true;
}
本来这个函数只要一个语句:
void function show_name(const user *aman)
{
	show(aman->get_name());
}
我不清楚上面哪一种方法更好,或者两种都不好。像:
	if(!check_system_show())
		return false;
本来可以移到程序初始化时做一次检查就行了,现在却每次调用show_name就检查一次,是极大的浪费行为!
但是,“不要做任何假设”,如果show_name被匆忙移到另一个地方,而那个地方初始时并没有做check_system_show检查,可能就是一个错误的隐患。如果这个隐患是静态的,在编译能发现,那还好办,只需在新地方的初始化时做一次check_system_show检查即可。
但(最怕这个字),如果这个错误是动态的呢?编译时正常,好了,这个函数现在被搁在新系统一个很深很隐蔽的角落,现在你的新系统一切工作正常,过了一个月,突然崩溃了,进行一翻绝地大搜索后发现是show_name函数的问题。是不是很后悔。
A.信任理论(门卫理论)
为一个简单的只有一行的show_name函数配上5,6行条件满足检查无疑是很变态的,但不检查又是很可怕,那后果,虽然发生的情况只有万分之一不到。
该何去何从?有一种理论,信任理论。当参数是从外部程序传入时,我严格检查每一项参数,如果是内部调用,这是可信任的,就省去大量的检查。这样参数有效性(及条件满足)检查就需布置在有限的几个对外接口处。这又叫门卫理论。
这似乎是一个完美的解决方法,效率与正确的完美结合。
B.安全函数
只是还有一点不完美,我们做了假设,我们假设内部函数就是内部函数,外部函数(即对外接口函数)就是外部函数。当内部函数变成了外部函数呢?
我看过一本书,上面说,代码的复制与粘贴速度远远超出我们的相象,一段代码,可能会像病毒一样被复制到每个地方。复制代码的人并不管你内部函数(内部代码)还是外部代码,只要当时运行正常就行了。
这样我们的门卫理论面临失败的危险,当门卫的函数(我们为赶时间临时复制过来的),它并不称职,它省略了很多门卫该做的检查。(哈哈,错误成功偷渡进入)
在程序员生涯开始的时候,我看过一本VB编程的书,上面提过一个“安全函数”的概念。所谓“安全函数”,就是不做任何假设的函数,它对每一个要用到的条件要输入的参数进行有效性检查,这种函数用“safe_”做函数名前缀。
看出来没有?这个“安全函数”真是天生的“门卫函数”,只要看到带“safe_”前缀的函数,我们可以放心拿过来放在任何位置,包括门口。
好了,参数有效性检查想说的也说了。到现在我也不知该用什么方法来进行参数有效检查,条件满足检查。所谓“安全函数”,“门卫函数”,我也并没有贯彻执行。我只是用最原始的第一种风格,当我认为这个函数足够重要。

5,大小写
变量名,函数名,类名,若是由两个单词组成,就面临至少两种选择。比如:
showname
可以写成show_name
也可写成ShowName
因为我以前有过很多次惨痛的经验。每次我在window2000下的文件名一到win98下就变成了大写,当我上传到unix服务器时这些文件全都不能在网站上访问,要一一把大写换成小写再重传。
所以我非常厌恶大小写混合的方式,一律用下划线"_"区分单词,无论是文件名还是变量名。
现在我开始接受大小写混写的变量名方式了,因为下划线也是个不小的负担,当一个变量名中有3,4个下划线,和一个小单词长度相当。
但是文件名我绝对只用小写。