关于软件开发、领域知识、职业危机以及UML的计算主义思考

最近无聊时候,常常在琢磨领域建模相关的问题,比如医学图像处理领域,一致性显示流程算不算领域知识?那卷积反投影呢?它们都可以放到模型里面去吗?这样的模型,对你最终的服务对象,产品定义和软件设计人员有用吗?对这些问题思考得越深入,往往就会离题越远。

--

21世纪,软件已经渗透进人类生活的每一个领域,从指头大小的音乐播放器到遍布全球的互联网络。为了开发出真正有用的软件,程序员要不断地学习不同领域的知识。在一个领域工作久了,程序员也就慢慢变成了这个领域的专家。于是,一部分人开始尝试定义需求,成为产品的设计者;一部分人干脆就进入他们的软件所服务的行业,成为有技术背景的营销人员或CIO。

在这个每个人(不管是小学生还是社会学博士)都会编程的时代,人们不禁要问,软件的核心价值到底是什么?是这些人职业生涯的跳板?还是各种传统行业附属品?对于后者,软件外包就是个典型。特别是在发展中国家,软件产业链的下游,不管你的公司名字有没有带上外包的字眼,只要你跟老外打交道,你大多都跟外包有关。

就算很多自称是软件领域的资深人士,他们要么为了写出高质量的系统级代码,也不得不慢慢成为精通计算机原理的硬件专家;要么为了编写优秀的文本和图像处理算法,也不得不成为统计学或数据处理领域的专家;要么为了成功组织和实施应用软件开发项目,也不得不慢慢成为精通他们的产品或项目所服务领域的运营规律的行业专家。在前几次工业革命时期,我们难以想象一个搞蒸汽机的人,还会关心一艘破冰船如何能浮在水上不沉,或者一辆洲际列车上各种工作人员是如何协作的。

一些人把这种现象归因于软件行业还太年轻,难以形成成熟的自成体系的东西,事实真的是这样么?要达到什么程度,软件行业才算成熟呢?这个行业跟其他各种行业的关联是如此之深,也许真有它成熟的那一天,那软件就真是无所不包,也什么都不是了。

我宁愿相信,软件是一种工程化的数学工具。就像传统的数值计算工具(比如计算器)也可以在不同行业广泛应用那样,现在大多数的程序员(也就是很多公司里被叫做软件工程师,而不是算法研究者的那些人)正是在为不同的行业生产各种非数值计算工具。

一些非数值计算的原理,如布尔代数、集合论、关系代数等,被用模型化的方式进行了封装,从而更加方便地为不同领域进行订制。这种模型化的方法在实践中得到了长足的发展,比如面向对象和设计模式,它们一层套一层,一层比一层远离基本的数学原理,一层比一层更接近于所服务的领域中的一些众所皆知的常识:比如文档是一个实体,但审批者就不是一个实体,而是一个角色,因为一个人既可以是审批者也可以是提交者。

越来越多的程序员开始工作在这种接近于常识的层面上,他们的代码也变成这些看似众所周知的常识的一种笨拙和机械的翻版。尽管如此,有些代码最后还是卖出了高价。于是他们渐渐淡忘了自己是如何来到这个层面上的,甚至开始诋毁他们的大学老师,为什么浪费时间教我们数学,而不是跳过数学直接教授面向对象和分析模式。而后者,是那么的简单实用,不管是一个小学生或者一个完全不懂计算机的老板,都可以很容易的理解。而往往老板都觉得自己都很容易做到的事情,他肯定不舍得花大价钱请人来做。

于是软件外包大量出现,很多地方的软件产业也叫做软件“服务”行业。但即便是在外包公司里面,大多数编程工作却更像是在生产一种“产品”。这些产品帮助职员和管理者提高工作流程和信息管理的效率,或者帮助医生、平面设计师或搜索引擎的用户方便地利用各种数值计算工具及其结果(别忘了,编写这些真正能卖钱的数值算法的人一般不叫做程序员,而叫做算法科学家)。这些软件有幸运行在电子化(至少目前为止还是基于电磁场原理)的计算设备上面,并跟随这些设备一起销售(虽然未必是同一家提供商),从而使得它们跟传统的数值计算工具(比如计算器或精算师)很不一样。当然,计算机也能做并且能做更加强大的数值计算,我们也没有必要评价数值和非数值计算谁好谁坏,或者谁更容易赚到钱,但我们必须承认,如果计算机只能做数值计算的话,也许不会带来真正意义上的信息化革命。

后来随着开源社区以及云计算的推进,代码本身开始变得越来越便宜。随着越来越多的代码变成完全免费,编写代码的工作才越来越接近真正意义上的“服务”。在我接触到一些互联网业者眼里,源代码保护是一个根本不值得讨论的问题。比如你用HTML5实现了某个很酷的功能,有一个人点击右键查看源代码,然后一步步破解并移植到自己的网站上,而另一个人模仿你的功能,自己重新实现一遍:其实他们这两个人花的时间和金钱并没有多大差别。

确实,如果没有涉及一些只有算法科学家研究出来的东西的话,大多数被叫做软件工程师的人做出来的东西,就会面临这样的境遇。也许在互联网以外的其他行业,软件开发工作的性质从产品制造转向服务提供,还有很长的路要走,但这已无可争议地成为一种趋势。

这样的转变,是好事还是坏事,完全取决于你自己的选择。如果你在熟练的编写代码(或者熟练的带领一堆人编写代码)之外一无所知的话,你的处境可能会变得有点困难。于是,你要么挖空心思把软件的“服务”做深,把产品做成平台,走向产业链高端,或者提供软件开发和管理技术咨询和培训;要么还是给自己装备一些非数值计算之外的所谓“领域知识”,比如图像处理、数据挖掘、设备控制原理、行业信息化经验、大众消费和社交习惯等。当然,还有很多其他选择,比如放弃技术,投身商海。

不管怎样,只要你还在编写软件,并且不想被可有可无的项目进度、乱七八糟的新技术、莫名其妙的职业危机困扰的话,你就得认清楚软件的本质和核心价值,并理解软件是怎么走到今天,以及明天可能会走向何方。

回到前面的话题吧:虽然计算机最初只是用来做解决数值计算的问题的,但正是这些看似小学生都能理解的非数值计算,触发了这次技术革命,并成为软件产业得以发展的原始动力。其实我们根本没有必要为能编写程序的小学生感到惊讶,因为他们同样也能组装出一台半导体收音机。亲自动手编程,几乎已经成为每个普通人理解这个时代正在发生的很多事情的唯一途径。

--

书柜的底部压着一本书,《嵌入式系统的微模块化程序设计》,是我多年前买的,一直没有机会看。买书的理由很简单,因为里面有一张用来描绘氢原子能级跃迁的UML状态图。顺带提一下,书的作者是一位曾经在GE医疗工作的软件架构师。

在量子力学打破经典物理学的统治之后,在人类社会的各个领域,数值计算工具正在变得越来越力不从心。人们发现数值计算只能处理一些不大不小的理想化的简单场景。在微观和宏观这两个极端出现的复杂性面前,人们只能用微积分和统计学给出一个大致的描述(比如概率和波函数),而无法精确分析每个个体的行为。在本来大量使用数值计算模型来解决问题的领域,非数值计算模型(比如元胞自动机之类)开始发挥越来越大的作用。很明显,UML天生具备了描述某些非数值计算模型的强大能力,并且比学院派教科书里面的形式逻辑更加容易理解。

如果用计算主义的视角观察这个世界,其实每个领域都存在着数值计算和非数值计算模型,在一些领域他们互为补充,在另一些领域也许其中的一方占有压倒性的优势。就拿信息化领域来说,一个精通某个领域的信息对象的处理规则和流转方式的人,未必需要知道信息量是如何定义和计算的,或者人们为什么非要使用比特这个单位。

有趣的是,越是传统的数值计算模型难以企及的领域(比如要监控流程中的每一道工序),对软件和一般程序员的依赖程度就越高。你可以想象一下,一个组织在没有建立起支撑内部精细作业流程的信息系统之前,讨论正态分布和西格码的取值是何等的空洞和乏味。

--

之前系统的一些问题,导致hertz同志的一个回复不小心被删掉了,
他提到:新时代软件工程的核心在于方法论。

很感谢hertz同志,软件工程的核心是方法论,确实是现在业界的共识。
我也曾经对这个观点深信不疑,但最近一两年似乎开始有点动摇。

在这之前,我曾关注过一阵软件架构和设计方法论,
时间再往前推,也关注过CMM和迭代之类的开发管理方法论。
随着了解的深入,我越发觉得方法论的研究已经遇到一些瓶颈,
就像摩尔定律最终可能止步于物理学定律那样。
其实,自70年代软件危机以来,方法论已经取得巨大的进步,
而未来的突破,只能等待认知科学或管理学的进展。

实际工作中的体会是:即便你方法论用得再好,
它终究还是一种外部的,指导性的最佳实践,或制度性的管理流程。
项目最终的成败还是取决于人,特别是人脑中的领域知识,
以及如何把这些领域知识转换成可编程的计算模型的能力。

我以前的一篇博客提到了一个案例,
正好能说明一个缺乏领域知识的团队,是如何在正确的方法论指导下做出错误的软件的。
当然你可以把责任推到选人、用人或知识管理的角度上,
但这就变成一个管理学问题,而非软件工程问题了。

这里说的领域知识既可以是一个编译器的工作原理,也可以是某个行业的信息化经验。
软件开发很多时候就是把领域知识转换成计算模型,然后编程实现出来,
这种转换有时会用到OO方法论,但有时未必。

对于一些新的领域(比如现在的云计算),这个转换的过程就像在荒原上旅行,
人走多了,路(即方法论,比如MapReduce之类的编程模型)才会慢慢显现。
也许方法论是软件工程需要关注的一种重要产出,但似乎不是最核心的驱动力。

 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页