不论是读书的时候做项目,还是在公司里看着一个产品从无到有,都是非常宝贵的成长经历。在这些实践过程中,最有价值的应该是对软件架构,或者说系统架构这方面的认识。
最开始写代码是从小学,那时候还是学习机和286时代。那时候写代码的目标就是写出最短的代码以及执行最快的代码。
到了大学开始学习计算机专业,在教授们的催眠作用下慢慢知道了设计要讲究模块化,也就仅此而已。唉,我又不得不说现在的大学教育了。如果自己不找个机会去动手、去实践的话,那四年一定是白费了,因为很少有学校还会逼着你去掌握实践技能,学校只会让你考试,让你做题。这是中国教育现在能做到的(不过当时我们学院提供的环境还不错)。
一、原型证明很重要,但是该扔就扔
一个项目到手上,除非是一个小项目,或者是一个做过了的项目,否则或多或少都会有一些未知领域,或者说是吃不准的领域。这时候怎么办?我发现很多有有个坏习惯,他们喜欢去翻书看看书上怎么讲。最明显的例子就是很多人都会说Oracle比MySQL好,一问为什么,他们就说“肯定是的”、“Oracle是企业级的”云云。还有一些人手头没有书,就跑道CSDN上去问,看看有没有高人指点。其实最好的办法就是:自己动手。
方法很简单,你觉得MySQL不好,就写个简单的benchmark测试一下就知道了。如果你发现它的性能已经完全满足你的要求了,你要的功能它也有了,而且你又想省一笔投资,那就用它好了(当然实际问题不是这么简单,我只是举个例子)。
另外一点也很重要,就是:原型代码一般是不需要什么良定义的,写它的目的是想证实一下自己的想法是可以实现的。因此,如果它没有完好的定义,就放弃它吧。新的代码重新架构。
二、关于模块问题
的确,一切系统都要求有很好的模块划分。不论是面向过程的,还是面向对象的,或者是面向其他的,模块化显然是一个很好的统称。但我的体会是:除非重复做一个项目,否则很多事情是预料不到的。虽然我们要对需求有深入的了解,对初步的设计也有了令人信服的原型证明,但是几乎还是会有意向不到的情况(除非项目很小),哪怕当初设计得再详细。这绝对是真的。
如果当初的架构有问题怎么办?我们曾经尝试过绕开它,有些时候是用一些很丑陋、很不常规的方法来避开它。这对于一个项目的架构而言是非常危险的。如果只有一个地方那个有些绕,那可能不是问题。但是模块A用了非常手段,模块B的作者一定会也用非常手段,发生这种事情原因很可能是现实的,例如模块B的作者可能想快点把事情做完。但是这样的结果就是模块之间的混乱程度增加了,项目到了后来就变得越来越难以维护。如果某个员工离职了,那么就项目接手的代价就非常大了,甚至是几个月的延误。
作为系统架构人员,另一个主要的职责就是保持模块之间的“概念完整性”。简单的说,就是模块之间的关系一定不能有丑陋的地方,和不常规的地方,架构人员要像对待一件艺术品一样来把关。否则这将是噩梦的开端。但是到了系统开发完毕,进入了性能调整的阶段的时候,可以在瓶颈的地方做一些小的手脚,这倒是无伤大雅。因为通常而言,系统的瓶颈不会太多,解决了几个重大的瓶颈,性能可能就会有数量级的提升。
三、架构需要考虑测试
我在项目的开发过程中发现,如果一开始架构的时候,或者是一个模块设计的时候,如果没有想过以后怎么测试它,那么这也会是一个噩梦的开始。
在“有道”搜索引擎的开发过程中,我深有体会。我让某某库(出于保密,我省去了具体的库名称)调用我写的代码。开发的时候感觉还不错,代码也还清晰易懂。但是到了需要测试的时候,我开始发怵了。我根本想不出有什么简单的方法来测试它,因为我几乎不知道调用我写的代码的参数是什么样子,那我怎么可能去伪造这个参数来测试这个过程呢?后来我屈服了,为测试用例而修改代码(这可不是什么好方法)!把我的代码封装到一个语意更明确的方法里,让某某库来调用这个新方法。而我的测试用例只用测试我新封装的方法就行了。
经过一次又一次的痛苦,我彻底明白为什么很多设计书上会说测试也是需要认真设计的了。
四、性能调优
一般系统的瓶颈一般都是那么几个,解决了他们就解决了80%的问题。现在有很多系统瓶颈的测量工具,不论是Java还是C++,应该是很好用的(最近Java6.0自带的JMX和相关的工具已经相当不错了)。关键的问题是在分析,找到关键点。这个需要一些积累,不是三言两语能讲清楚的(其实我的经验也不错)。
关于这个话题就到这里吧。以后想起来再写。
没有评论:
发表评论