来博客园有不少日子了,园子一个不变的主题就是捯饬这些。说点我的看法。
本来想正经写文发到首页的。不过算了,目前害怕在这类问题上交流讨论。且我不看好这个讨论对我自己和其他人的价值。
实际上如何组织程序应该从需求出发,而根本不像那些设计指南里说的应该这样应该那样,而不顾前提。这个前提的关键在于你的用户是谁。对于组织这项工作及其结果来说,有俩,一个是咱们自己,一个是其它程序员。
而在应用开发这个水平上,真正为别人设计的时候并不多,而且不具有商业中间件那么重要的意义。
无论是沉浸在面向对象,还是一个非常朴素的程序员,只要我们认真负责,总能设计出不错的接口甚至框架。面条式代码的错误不在于不熟悉某某具体的原则,在于一个人的责任心,这是很多人没有明白的事情。
我逐渐知道,即便一些表现的很热情的学习者,也不过是认为懂得面向对象能更好的找工作(或者是类似潜意识的驱动)。所以我对讨论这些话题,逐渐的从积极参与变成了一个沉默者。因为最终这种讨论变得不击中实质,没有任何指导意义。
划定用户,从需求出发,经过一两个回合的实践,总能找到*目前*较好的一个设计(而不必学习思考太多预备知识)。这无需由任何方法论支撑,它们也无力承受。至于具体的工具(语言或框架),仅仅是为了加快工作速度用的。
不同的设施会有不同的加速指数,所以对工具的广泛了解还是需要的;但必须仅仅从实在方便性上而不是阳春白雪上看这些问题。
我也不赞成通过成熟框架来肯定自己的学习并得出结论的做法。尤其是对于有些程序员,他面临的情景和作者相差太多。
比如ASP.NET这类样的框架和带有的库,有很多设计上的缺点,水平不够的学习者将会很长时间的东施效颦。即便是很多好的决定,仅仅是设计者考虑他认为的最大一部分用户共同的需求才导致的。
不了解这些瞎印证,有不少得出错误结论的几率。而哪怕只有1%的错误,也会影响我们未来的判断。更何况即便找对了路子又能怎样呢?马后炮的人总是马后炮,因为他已经习惯了这个模式;解释正确并不意味着学到了真功夫。
关于对框架的学习,我倒是有一个看法,不妨常常问问自己一些问题。比如“把ASP.NET放到Python的世界,会有人用吗?”
当一个人的选择有限,他就希望这个选择是合理的;那些明显认为不好的,也感觉“无伤大雅”或者认为是Trade Off。当我们跳开这个圈子,看看其它人的选择,最终也许我们就会基于比如Handler自己开发一个东西来用。
就ASP.NET这个例子,虽然没法发放调查问卷,但无论是WebForm还是当前的MVC,恐怕都有不小的几率得到反对的答案。接下来问问为什么、会和不会的都是哪些用户;于是就知道这个东西不好在哪里,或者好在哪里。
有了这些素材,就可以判断自己是不是某个东西的目标用户;如果在很大程度上你和不选择它的那些人有共鸣,它就不适合你了。这时候很多特性,到底应该怎么评价也就变得客观;而不是在很小的一亩三分地上,“哦,这个设计应该是那么考虑的”。
所以你看,这些问题的答案,最终都会和用户是谁,他们(包括我们自己)想要怎么样相关的。
回头说说大多数人所谓的设计,也就是怎么组织程序。有了上面的讨论,不难看出很多看似有价值的文章说的都是废话。我们总能找出不错的理由支持这样或者那样的设计(当然如果这个设计还能被肯定或部分肯定,这也说明它的作者是有一定责任心的)。
但我认为,过了初学者的阶段,当我们碰到真正复杂的问题时,这种学习就变得没有意义甚至拖后腿了。你不能假象你在设计ASP.NET,因为你确实不是。基于其作者的视角和理由去设计自己的东西,最终只能是绣花枕头。毕竟,用户群和问题规模根本就不一样。
每件多余的东西都会付出代价,请注意这一点。奥卡姆剃刀不仅仅用在面向对象内部,对是不是采用某理念照样适用。大家都很希望自己是个了不起的设计师,但什么时候也不能依赖于遐想。象“某牛那样做决定”这是好的,但是往往我们没有看到“某牛在我们这个位置上会怎么决定”。
问问自己,我现在掌握了这么多,我能设计出ASP.NET吗?如果不能,问问自己为什么。我个人的一个答案是,这往往是因为我们没学会正确的方法:即仅通过需求做决定,而不是无谓的琢磨先验知识。
不想当将军的士兵不是好士兵;但是不根据形势而根据内心期许做眼前决定的一定不能当将军。
最后从应用和底层的关系再来看看相同的问题。
想作为一个纯粹的程序员变得更强,就必须认识到真实状况。实际上底层程序员和应用程序员面对的复杂度不是一个级别的。这一点上不能自己骗自己,因为用户群及需要考虑的各方面需求及其数量级都是不同的。
当然,你可以拿一个好的应用程序员去鄙视一个差的底层程序员,但这种自我(群体)肯定,是不讲健康的。当我们认为我们和底层程序员一样棒,甚至和Linus一样棒,我们就会忽略这类大牛不在乎的东西;并以“纯粹的程序员”自豪。
可事实上,很多底层程序员关心的东西我们却也没关心(根本没机会),最终只好搞些徒耗精力的学问求一个充实感。
就我看,作为一个应用程序员,如果说和底层程序员不分高下的话,我们就应该关心很多其它的事情。这些事情是什么,是和你的工作角色相关的。也许是业务也许是其它的,总之你得去挖掘下游的需求(又回到这上面来了)。
甚至我们就不能把自己当作程序员,而是作为一个领域专家,熟悉业务以及业务如何多快好省的实现就够了。
这两个领域的差别带来的区别,也有很多值得玩味的内容。
比如有人说,Linus炮轰面向对象,是因为他和应用程序员面对的领域不同。这话很恶心。
如果一个程序员看不出不同层次不同领域的共性,他也没有真正理解面向对象。但看出来了会如何选择呢?事实上之所以很多方法又漂亮又好使,不过是因为这些方法绝大多数时候只能运用在简单的问题上罢了。
任何方法运用在简单问题上都能找出漂亮的方案。也很容易观察到,除了少数领域,方法论闹得最凶的都是题目相对简单(也许很“高级”)的应用或中间件社区;而大多数热火朝天的学习、实践者又偏偏都不是干少数领域的。
为什么?因为方法论好的一面容易表现出来,自然就吸引人。可最终因为简单,所以其它方法也行得通;这样这些方法论却又不能一统天下。这样它们在大众社区里就表现出一种尴尬:你可以在那津津有味的探讨扩展、重用及其背后的原则,可是难题还是难题,容易的还是容易的。
这就说明,我们每个人碰到的问题,解决之道根本不在我们到底掌握了什么没掌握什么。这不是说某方法论就不能使了,给自己的工具箱添加一些新东西是必要的;只是我们必须避免增加不必要的冗余。
要做到这一点就必须“惰性”一点,只有明显感觉到优势时才使用更多的工具。这样,我们就在多了一种工具的同时,避免了背上Linus所说的“精神包袱”。也许我们应该有一张表,这张表是通过“需求->实践->经验->带有条件的结论”得到的。它记录了工具和场景的一些联系。
而过多的讨论和研习,就相当于:没有正确的、*真正*问题前,我们就回答了它。