-
软件工程的目的在于平衡资源、效率与质量之间的平衡,应用到架构与细节设计的层面就会集中在开发效率与质量上。传统的工程哲学认为,在设计开发之初明确需求,在设计开发与维护的全程随时跟踪质量。而对于需求变更的情况,要么让客户为变更的需求支付额外的成本,要么在原有的的架构上做一些拙劣的修补。这两种应对措施一个是阻碍问题,一个是掩盖问题,这种不合作的态度多少显示出传统软件工程在应对变化时的无能。
是什么造成了这种不合作的态度?是设计。软件工程虽然没有对架构与细节设计做过多的干预,但是对效率和质量却有硬性要求。大多数设计者脑袋里不停回响的三个词就是“效率,效率,效率”,而作为coder出身的他们也更倾向于向coding的过程要效率,于是,层出不穷的快速开发工具、框架,各种名目繁多的设计架构,几乎都不外乎是为了减少开发人员的敲代码的工作量。它们有时习惯于把一段看似复杂的逻辑包装成简单的接口,有时又会为一些简单的任务设计出庞大华丽而又臃肿笨拙的结构。
我刚刚看过一篇ASP.NET的技术文章,作者仅仅为了生成一段HTML,华丽而又炫技的使用了user control, customized HttpHandler, IIS ISAPI Mapping以及JavaScript的prototype Ajax framework.这个方案的唯一目的是避免页面刷新,唯一优点是提高user control的复用性,却引入了client id conflict的问题(更不用说这样的user control无法支持postback)。这个时候,一个回复者又创造性的提出了“自己维护控件树”的修补方案——我的亲娘啊,这就是我们现在软件工业的设计者和开发者们。
除此以外,我还亲眼见过那种用xsl来包装JavaScript框架,然后用自定义的server control来生成xsl,然后在user control中进行xslt,然后用Altas框架加载这些user control,最后还用JavaScript去填补Atlas的设计方案。对了,我忘了说作为xml的数据源是怎么来的:将xml数据插入Diesel Engine,然后创建一个web service来query这些数据,接着用一个模块将query来数据插入数据库,然后再从数据库中读取这些数据,然后再将这些数据转换成xml——由于这些不同的工作都由不同的team开发,所以大家都尽可能的发挥的主观能动性来增加系统复杂度:设计web service的人使用了最新的.NET SOA框架,设计读取数据库的人使用了Nhibernate框架。你也许觉得眼熟,这套设计方案非常像那些胎死腹中的“大项目”,实际上,它不仅仅是胎死腹中而已,它甚至把整个公司都拖下了水——因为难以快速响应客户的需求变更,公司错过了最重要的几个订单,接下来几个关键的项目负责人因为缺乏维护的信心或者要做替罪羊而离开公司,最后项目难以为继,公司被兼并,故事结束。
我觉得那些客户肯定会一头雾水,他们只是想要一个普通的电子商务网站而已,能罗列商品信息,能让客户订购商品,只是这么简单的需求,竟然需要长达近2年的开发周期——他们当然不会知道,他们需要的功能其实在最初的2个月内就开发完成了,剩下的时间就是在将这个项目变得足够大,足够复杂,足够难以维护。
(待续)







