感觉好多了
其实我并没有用 lua 亲手写过什么大规模的项目。超过 5 千行代码的项目几乎都是 C 或是 C++ 写的。这几天算是做了点复杂的玩意了。几经修改和删减,最后接近完工的这个东西统计下来不多不少 3000 行(误差在十位数)。其中用 C 编写了基础模块 900 多行(仅仅是 socket api 的封装和 byte 流的编码解码),剩下的都是用 lua 设计并实现的。
好吧,我承认 2000 多行代码也只是一个小东西。不过用 lua 实现的一个 wiki 系统,sputnik 还不到 2000 行呢。lua 有一种特质,用的久了就容易体会到。它和 python ruby 这些更为流行的动态语言是不同的。曾经,我把选择 lua 的理由,肤浅的停留在了更轻便更高效上,虽然这些也很重要,但抓住语言的特质才是更关键的。
没有一所学校会教授 lua 这种小语言。教学语言多为 C C++ java (或者更古老一些的 fortran lisp ?)。近年来有听说教 python 的,不过我想 lua 很难进入教学领域。所以大多数用 lua 的程序员,基本上都是半路出家,用过别语言。其中以 C/C++ 为多。我想这是因为 lua 不像 python 有太多成熟的库可以直接使用,要用之到实际项目中去,用 C 为它写扩展必不可少。
或许日后,lua 的扩展库会越来越丰富,lua 程序员不再需要亲自操刀写扩展模块。但就现状来说,我认为也不是坏事。毕竟自己实现的东西最熟悉,(包括 lua 本身的 source code ,规模也不算大,值得一读),知道其性能要点,怎么使用最适宜。
lua 的语言相当简洁,数据类型也少到了极致,真是增一分便觉多余,减一点就有缺陷。这样,我们便不用再把语言用的不好归结到语言的设计本身上。深刻理解它就能用起来游刃有余。
几乎每个 lua 程序员独立写出来的代码都风格迥异。因为我们既可以以面向对象的形式来构建系统,又能够把它当函数式语言实用,还可以直接来描述数据(这是 lua 1.0 的最初用途)。虽然这样,会给大规模项目的多人合作造成一些困扰。但我们能面对多大的项目呢?让我们项目的构架师去把项目划成更小的独立组件,然后用 lua 快乐的实现它。让原本用别的语言需要上万行的工作用 lua 在两三千行中解决。
lua 中复杂的对象类型只有 table 和 userdata 两个。
userdata 往往比较单一,只用来处理效率紧要的数据。这些是放在 C 层次中做的,很容易隔离开。(当然,用之不慎也会出许多问题。不过多为新的 lua 程序员缺乏经验,把 lua 简单看成一个 C 代码粘合剂所致。)
真正复杂的只有 table ,它回相互链接,构成复杂的生存依赖关系。而另外跟垃圾收集有关的类似,比如 string 和 closure (以及后来增加的 thread )则不会带来太多的复杂度。
强调数据类型的复杂度,是关系到垃圾收集的过程。我们知道,lua 这类语言中,不存在 C 语言里的指针越界和内存泄露问题。但是,我不相信垃圾收集就是万能药,在不成熟或有疏漏的设计中,问题只是被隐藏起来了。
所以在 C 或 C++ 中,我们关注数据的内存布局,和内存管理;到了 lua 中,我们也应该关心数据何种情况下诞生,何种情况下消亡。怎样减少垃圾收集器的工作压力。后者并不比前者容易,因为前者往往会引起系统崩溃,给开发人员预警;而后者,表象可能仅仅是系统资源占用过大而已。不引起程序崩溃的失误才是最可怕的。
如果,有性能追求的程序员了解到,每次创建一个新的 table ,构造一个新的 closure ,用连接符连接一个新的 string ,都有新的对象诞生。哪怕它只是临时用几个 circle ,也会给事后的垃圾收集模块造成压力。那么,当他在设计上尽量减少这些事情的发生,且尽量维持着代码规模不至于过大。那么,稳定的系统自然而生。这也是我最近半个月用 lua 编程的感受。
语言,看似是软件设计中枝梢末节的部分。但是语言同样深刻的影响着设计师的思维方式。作为程序员,对单一语言过分依赖的时候,就应该引起自己的警觉,该试点新的思路了。
换个角度再写点别的。
最近很忙,而今天有时间写这么大一篇,纯属无奈。手头一个项目,我自己的部分都做完了。剩下的依赖其他同事一起工作,需要做一些通讯协议上的修正。不过今天是周末,我带团队的原则是,不到万不得已,绝不要求别人加班。写完今天最后一行代码前,已经想过了可以提前写的代码,能做的都做了,剩下的只能等周一继续。
把大项目拆分成独立的二进制模块,分配到不同的人来做。是我最为(也是唯一)认可的中型软件项目的合作开发模式。在游戏客户端这边,基本上是独立模块,留出极少的 C 接口;服务器那边则干脆做成一个个独立进程,之间用通讯协议来协同运行。
经历了太多事情,让我对源码级上的合作失去了信心。或许 XP 的结对编程会好一些,不过前几年尝试的经历让我感觉那样太累。还是一个人对着电脑做东西好。当然前提是个人能力要达到一定的程度,并对编程这件事有足够良性的态度,才能保证代码质量。
代码质量如何保证?我的私人药方是,把一切事情简单化,尽量把代码写短(保持每个独立源文件不超过 500 行),删掉和缩减一切不必要的东西。让 bug 无处发生,比小心的回避它们要容易的多。不行就重写,而不要过多调试。不要在一块代码上耽误太多时间,速战速决。如果花了太多时间去实现它,那么一定有设计问题。世界上有许多复杂的事情难以解决,但绝对不包括实现一个有特定需求的模块 :D 。
怎样高效的完成一个软件项目?选择最好的程序员,不要太多,不要觉得小题大作。把他们放在一起,在一两个月内完成它。如果做不到,比如找不到最好的程序员,只要你相信自己就是最好的,那么即使一个人单干也好过雇一大堆平庸的人去做。当然,再好的程序员也不能同时做两件事情。所以,设定好计划,一件事一件事的来。
程序员们总是高估计自己的能力,而低估问题的复杂度。在多个合作的项目中更为突出。一个人两周的工作,即使两个同样优秀的人一起干,也不会把工期缩短到一周(甚至加到 3 个人也做不到)。道理看上去大家都懂,但是事到临头还是会为多人合作的效率低下而懊恼。可惜,许多许多的现实项目,在不至于引发疲倦的工期内,靠一个人是写不完程序的。何况,像我所处的游戏开发行业内,一个项目不仅仅是靠程序实现。我们还是得面对合作开发这个问题。
Comments
Posted by: 过客 | (28) February 17, 2012 11:17 AM
Posted by: jay | (27) November 23, 2009 05:19 PM
Posted by: 松鼠 | (26) January 13, 2009 01:52 PM
Posted by: today | (25) April 6, 2008 09:58 PM
Posted by: xtypebee | (24) April 1, 2008 10:05 AM
Posted by: 可丁小子 | (23) March 29, 2008 12:19 PM
Posted by: 安德尔斯 | (22) March 27, 2008 08:20 AM
Posted by: yafare | (21) March 26, 2008 11:43 PM
Posted by: 满招损 | (20) March 26, 2008 11:29 PM
Posted by: janson | (19) March 26, 2008 03:21 PM
Posted by: 一个fan | (18) March 25, 2008 10:02 PM
Posted by: Echo. | (17) March 25, 2008 08:17 PM
Posted by: Rain | (16) March 25, 2008 09:12 AM
Posted by: congy | (15) March 24, 2008 09:45 PM
Posted by: Cloud | (14) March 24, 2008 06:48 PM
Posted by: 将军的故事 | (13) March 24, 2008 04:33 PM
Posted by: Xiaofeng | (12) March 24, 2008 01:54 PM
Posted by: nothanks | (11) March 24, 2008 01:06 PM
Posted by: lbaby | (10) March 24, 2008 09:58 AM
Posted by: sjinny | (9) March 23, 2008 07:06 PM
Posted by: nothanks | (8) March 23, 2008 01:30 PM
Posted by: Xiaofeng | (7) March 23, 2008 02:17 AM
Posted by: Cloud | (6) March 23, 2008 01:25 AM
Posted by: Anonymous | (5) March 23, 2008 01:14 AM
Posted by: 无所谓 | (4) March 23, 2008 12:23 AM
Posted by: Mao.. | (3) March 23, 2008 12:17 AM
Posted by: flycondor | (2) March 22, 2008 10:24 PM
Posted by: crazymader | (1) March 22, 2008 09:27 PM