本文由Yurii原创,转载请注明来源: Life Sailor

本文链接 程序可以止步于接口,思维不能


“面向接口编程”是程序设计的规则之一,它可以将具体实现封装为具有一定逻辑意义的抽象行为。这样做的好处多多,比如有利于在较高层次上思考,而不必操心细节;比如避免外部代码因为具体实现变化而作修改。广大开发人员,不管自己设计程序时有没有注意“面向接口编程”,都会或多或少地从“面向接口编程”中获益——我上大学时曾听某师兄说:“编程还不容易,从网络上找一些类库来调用就好了”。接口隐藏了背后的实现,可是,许多开发人员不但写程序止步于接口,思维同样止步于接口。接口背后是什么,他们写的程序不关心,他们自己也不关心,而且振振有词“我这是面向接口编程”。但是,这真的是好事吗?

我刚工作时,所做的项目里有几个问题是自己搞不定的,甚至整个项目组也没有人能搞定。好在项目经理很有办法,找了他之前的同事兼职帮忙,写出最难的模块,我们只管调用现成接口就可以了。当时大家都松了一口气,至少不会因为自己水平不够,耽误项目进展了,内心也非常感激这位兼职的高人。可是,随着项目的进展,我们搞不定的问题越来越多,于是越来越依赖兼职的帮忙,整个项目也因此越来越被动。我仔细观察,发现这类搞不定的问题虽然反复出现,归结起来只集中在某几个领域,而每次这位兼职高人给过来的程序,尺寸变化并不大。所以我认定,这些问题并没有太多难度,只要解决其中一个,应该就可以举一反三,顺势全部解决。于是我花了一周的业余时间,逐行细抠接口之后的代码,终于尝试独立解决了一个这类问题,给项目经理看过,他非常高兴,从此甚至对我有些另眼相待。当时我想,他这么高兴,是因为我为公司省了钱,再也不必烦劳以前的同事兼职了罢。

过了许多年,我又见过了一次这种场景,只不过这一次我的角色调换过来。有些工作确实可以简单调用一些现成的模块解决,但有员工会积极探索这些模块背后的细节:它是怎么解决这个问题的?这种做法有什么好处,什么坏处?如果我们需要改进,应该从哪里入手?……能够思索这些细节,就会更深入地理解自己所要解决的问题,而且面对意外也不会一筹莫展——“就是这样的,我也不知道为什么”,出现问题时听到这样的话,真能把人气得七窍生烟。两相对比,我才真正理解当年项目经理那么高兴的原因:遇到愿意探究接口背后实现细节的程序员,因为欣赏而高兴,这应当是人之常情吧。
回想我自己的工作经历,并没有花太多的力气去专门学习某些知识,但还是略有积累,相当程度上也是因为自己有一点“探究接口背后实现”的兴趣和气力。比如学会每一种语言,都愿意自己写一个带输出的比较函数,去看看它的排序是用的哪种算法,由此掌握了好几种没学过的排序算法;再比如用Lucene做全文检索时,除去调用那些现成的接口,还认真看了Lucene的实现原理和算分公式,于是知道了哪些地方适合进行定制,定制时应当从哪里切入;继续深入,又读了几本关于搜索引擎的专著,知道如何评价搜索,搜索服务在产品方面应当注意哪些……

这类“接口之后”的问题,了解了,思考了,并不一定用得上,但确实让人受益匪浅:第一,它拓展了视野,构建了更多知识联接,让我们在思考问题时有更广阔的思路;第二,它深化了对问题的理解,许多看似独立的问题,深入到一定层次就会发现其实是相通的。作为对比,我曾经见过许多开发人员,他们会调用语言内建的排序函数,却无法根据数据的规模选择合理的排序算法,数据量稍大一些则束手无策;他们也会照抄网上的Lucene代码来搭建一个搜索服务,但遇到复杂文档或是复杂搜索就只能干巴巴期望官方更新会提供这个功能。这样的开发人员有不少,他们能干活,却很难攻坚,所以价值也会打个折扣。这一切很大程度上是因为程序止步于接口,思维也止步于接口(更可气的是遇到这类说辞“工作没意思,因为学不到什么东西,永远是调用一些现成的模块”……)。

软件工程中有本书叫《门后的秘密:卓越管理的故事》,这本书的内容不错,但我觉得书名取得更有意思——卓越管理的秘密,其实藏在门后。软件开发也是这个道理:现成的模块接口往往像通往神秘之地的门,如果我们只满足于在门外领取神奇的结果,不愿意探究门后的秘密,卓越的软件开发对我们来说,就永远是神秘不可捉摸的。