您的位置:首页 > 其它

随想:自己有眼不识泰山,现在发现了那是一个别有洞天的世界

2004-12-06 14:25 405 查看
很让人费解的标题,通常来说,程序员都是开发者。没错,对于我们的用户而言,我们是开发者,因此,对他们而言,我们拥有着无尽的魔力,可以创造出另外一个世界,而他们只能在我们圈出的土地上活动。不过,你是否想过这样的问题,在我们为别人指出一条明路的同时,自己也正在别人的鼓掌之中起舞。
作为程序员,我们经常会做一些框架的用户。想必Java程序员们对于servlet并不陌生,很长一段时间内,我一直把它当作一个普通的API,需要的时候能找到有哪些方法足矣。近来在考虑系统结构的设计,实现了一个简单的生命周期框架,其中有一个生命周期事件监听的机制。所谓监听不过是Observer模式的一种实现,也就是发生特定事件之后,调用监听器通知它们发生了些什么。信手翻起手边的《Java与模式》,《Servlet技术中的模式》一章一下子吸引了我。虽然以前也曾经看过这章,但站在用户的角度,我只是想了解有些什么,而从未考虑过这些东西为什么这样设计,当我成为一个开发者,却发现了那是一个别有洞天的世界,Servlet技术中的一些概念一下子涌上心头,细细品味,原来它与心中构想的框架有着许多相通之处:各种Listener(ServletContextListener、ServletContextAttributeListener、HttpSessionListener、HttpSessionAttributeListener)提供的就是我要设计的监听机制,而Filter则与我构想中Interceptor机制异曲同工(JBoss的灵活就是由Interceptor达成的),Servlet在我的设计中对应了最核心的Service。我在思考框架设计的时候,灵活性是一个很重要的因素,与Servlet的印证,让我重新认识了这个熟悉的陌生人。好东西就在身边,只是自己有眼不识泰山罢了。对于框架而言,其设计者是这场游戏中最快乐的人,除了会得到开发过程中的乐趣之外,为别人制订规则的乐趣也是超乎想象的。

框架设计者在得到属于自己的快乐同时,他们还要遵守语言设计者制订的规则。举个简单的例子,我们知道C++语言在C原有的值(value)、指针(pointer)基础之上又增加了一种引用(reference)。C语言已经用事实证明了自己的无所不能,值和指针已经足够完成所有的需求,而引用有不像类(class)、模板(template)之类的概念能够提供另一种抽象,那它的意义何在呢?我的答案是它不过是一种语法上的便利而已。在编译器实现的过程中,引用会以指针的形式表现出来,而在代码中展现出来的时候,它与普通的值丝毫不差。作为函数的客户端,代码编写时不再像以前指针那样需要额外的使用‘&’,这样代码看上去会干净许多,而效率上有不会有丝毫的损失。正是看中了这种代码上的干净,Java干脆去掉了指针,而丰富了引用的概念(可以置空、可以改写等等)。设计者体会到各种乐趣之后,给我们的只是一个设计的结果,不明就里的我们大多数情况下只能糊涂的遵循,而无法分享其中的乐趣。

再来举一个例子,C++中有拷贝构造函数的概念,其实在Java中我们也会有用一个对象构造另一个对象的情况,但Java人却从不提及这个概念,这是为什么呢?原因在于C++中存在的pass by value。虽然在优秀的编程风格时,我们会尽量使用pass by reference,但pass by value依然不可避免,比如构造一个有理数类的乘法运算,我们只能以pass by value的方式将函数中构造出来用以存放乘积的临时变量传递到函数外部。pass by value就必须存在一个拷贝构造的过程,我们不可能直接将一块内存直接复制到另一边,因为如果类定义中存动态分配内存的部分(也就是指针),代码就会存在问题。关于这个问题,《Effective C++》有详细的讲解。为什么Java中不存在这个问题呢?因为Java中来回传递的都是引用,不涉及拷贝构造的过程。那C++中就不能像Java一样吗?抱歉,不能。前面说的pass by value不可避免的一个重要原因在于你不能把局部变量传出来,因为局部变量的内存会在函数执行完之后销毁,我们会因此体会dangling的现象。如果是动态分配的呢?在函数中new出一个对象传出去可不是一个很好的行为,那样我们至少要在文档中多费一些口舌来说明这块内存由谁释放。Java中为什么没有这样的问题,因为Java的内存是由GC负责。现在我们可以看出,GC决不止是内存管理这么简单,它的影响甚远得很。

开发者和用户所能体会到的乐趣是不同。有许多人会认为软件开发了无生趣,很重要的一个原因在于他们只是规则的遵守者,而制订者对这场游戏则是乐此不疲。现在许多软件开发的书籍可以告诉你“HOW”,却很少说“WHY”。比如许多源码剖析的书,它会告诉你这段代码如何完成了功能,这种书看完之后,我们至多能够照猫画虎描出一个简单的例子,如果让我们自己来做,却往往不知道如何下手。因为我们只看到了结果,而没有其中的过程未能展现出来,而这个过程往往才是精华所在。

似乎制订规则是一件很遥远的事情,其实作为自己软件的开发者,我们又何尝不是规则的制订者。尝试站在规则制订的角度理解一些问题,既可以学习规则制订的法则,也能提升自己对规则的认识,这样我们才能在这场游戏中更加游刃有余。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: