最隐晦的程序设计指引

标签: 程序设计 | 发表时间:2011-07-24 23:14 | 作者:Nightmare Sirius
出处:http://blog.csdn.net/Nightmare
一、百家争鸣

    俗话说,程序员半年不学新东西,就变奥特曼(out man,过时之人)了。IT行业可以说是变化最快的行业,每年都有大量的新概念、新术语、新技术被创造出来,在多数人还在一头雾水时,“更好的”替代品又被创造出来。别的不说了,单说设计方法。

    想当年静态类型系统是王道,谁要是搞点运行时动态绑定、用点VB什么的,经常会被鄙视。而今动态类型语言大热,常有人高呼Python万岁,JavaScript身价百倍,C#也加入了动态类型支持。当年面向对象与过程式编程争吵不休,如今大家都在盯着函数式模式,C#和C++0x都加入了函数式语言特性。当我们学面向对象时,Gang of Four(据证实,这个书名确实是四人帮的英文翻译,故意调侃四位作者为坏家伙之意。)的设计模式流行起来了,当我们学Gang of Four时,其中一些模式被批为重复、过时、不宜的,一批表达新观点的书籍出版了(如Agile Modeling with Patterns)。当我们开始尝试敏捷方法时,模型驱动开发(Model Driven Development)遍布书刊封面和新闻头条,而当我们学用Rose、Visio画UML时,测试驱动开发(Test Driven Development)被提出来了。

    当然,历史的发展也常常会出人意料。人们曾经认为,动态的web必定需要Flash这样的新解决方案,而今HTML5+JavaScript不但可以取代Flash,还可以做3D应用。人们曾经认为,WebService需要一套新的行业标准,于是指定了SOAP等一系列协议,并历时数年时间开发了大量WebService平台和相关工具,而如今大家更喜欢基于基本的HTTP协议的REST方式和JavaScript本身的JSON数据协议,而且要简单高效得多。

    但究竟什么才是好的设计呢?如果静态类型系统才算好,那么大量优秀的动态类型语言程序算什么?如果面向对象才算好,那么大量优秀个过程式、函数式程序算什么?当年不知道匈牙利表示法的程序员就不是好coder,如今微软的态度是,别再提了。曾经OLE的程序员可以拿到高一倍的薪水,如今谁还会提OLE。Java阵营前些年喜欢嘲笑微软不懂Pattern,以致微软这些年有事没事地把Pattern挂在嘴边,但是如今被批评得一无是处的COM(1993)却是在Java诞生(1995)前就完美地实现了大多数的Java常用Pattern。既然COM被评价得这么烂,业界却搞出了一个和DCOM/COM+非常类似的CORBA。

    学过的人会说,低耦合、高内聚,如是等等。没错,这是一般原则,但也有情况下必须违背这些原则才是好的设计,典型的如性能优先的情况。再比如,一般原则有说状态查询和修改要分开,不要写在一个函数里,但是远程调用时却经常要合并,因为设计成网络往返通信两次不如一次解决。再比如,Java上有个著名的Spring Framework,可以利用反射功能,把程序中的动态选择性初始化问题转变成配置文件的设置,从而避免if语句(有个反if语句运动),Java程序员为此自豪。而同样的方法对主要用于桌面开发的.NET并不太适用,因为没有专业部署人员为桌面程序用户修改配置文件、填写正确的类名,而且桌面程序通常要做代码混淆(Obfuscation),会导致基于类名的反射失效。

    代码质量管理也是近些年的新热点,除了FxCop等传统检查分析工具外,计算复杂度的Cyclomatic Complexity方法和Test Coverage等量化分析得到了非常多的关注。这些工具对源码宏观分析提供了有效的手段。但分数高就代表代码质量一定高吗?尤其是对不懂技术的管理层,这些统计结果很容易成为财务报表一样的存在。

二、事有本末

    退一步想,当我们学自己的母语时,我们是先会说话还是先学语法呢?当我们学外语时,是先学说话还是先学语法呢?当我们读一首诗时,我们是先感觉到好还是先用各种规则去衡量它呢?当被要求说明哪里好时,是直接就说得出来还是要去借用各种规则来描述它的好?你是否隐约感觉到,有某种先于规则、方法存在的东西,但又难以言表,而必须用各种规则来间接地去描述它?

    有个春秋时期的故事,说齐桓公在堂上读书,工匠轮扁在堂下干活。轮扁问桓公说,敢问公读的什么书?桓公答,圣人之言。轮扁问,圣人还在吗?桓公答,已经死了。轮扁于是说,那么您读的就是古人的糟粕了。桓公大怒,说,寡人读书,轮得到你个车轮匠议论吗!说得出道理则罢,说不出就去死!轮扁答,用臣砍造车轮来说,慢了会甘滑而不牢固,快了会苦涩而难以敲入。唯有不快不慢,得于手而应于心。其中门道我也表达不出来,也无法传授给我儿子,所以如今七十岁了还在造轮子。圣人和他不可传的东西都已经消失了,那么您所读的,不就是剩下来的糟粕了吗?

    回到程序设计上,我们不断创造各种各样的方法、原则,到底是为了什么呢?当然是为了写出好程序。但到底什么是好?说不清。但可以肯定的是,都是为了好的性价比。性价比可以分成收益和代价。收益可以分成功能、性能、易用性、稳定性、安全性等等。代价可以分为开发时间成本、人力成本、可维护性等等。可维护性可以分为可读性、可扩展性、可复用性,如是等等,以指数级细化下去。然后有各种各样的方法,来解决各种具体的问题。如果开发时间不确定性大而却有严格的deadline,那么敏捷方法可以保证总是有个可用的发布版本,即使可能牺牲一些功能。如果代码只是短暂使用,或是被替代、重写的概率很大,那么可以完全不在乎可维护性,直接写抛弃型代码。如果代码面临高度频繁更改的可能性,那么用脚本语言吧。如果有个较大的开发团队,模型设计将有效提高交流沟通的效率。如果一个程序员在一个面向对象的系统中加入了一个处理算法,他的思路和实现都是过程式的,那么完全没必要把它改成面向对象的,因为那样只会增加额外的复杂度和理解困难,而且很难说日后算法修改后这个对象设计还能适用。如是等等。

    但是,因为这个精髓的东西难以说明,我们要么得在不断实践中慢慢领悟,要么学习别人总结出的方法来接近它。但是,人们经常纠结于方法本身。

    心都子讲过一个故事,说兄弟三人在齐鲁学儒术,学成回家,父亲问他们,仁义之道是什么?老大答,仁义使我爱身而后名。老二答,仁义使我杀身以成名。老三答,仁义使我身名并全。三个回答相反,却又同出于儒,谁是谁非?你纠结了吗?

    有句经常被引用的话:Any software problem can be solved by adding another layer of indirection. ——Steven M. Bellovin 其实原文后面还有半句:But that usually creates another problem.

    有个Java程序员写过一篇很有趣的blog。大意说,有个人要钉个钉子挂画框,于是去工具店买个锤子。店主说,No,我们已经不卖锤子了。锤子有很多种,大锤、拔钉锤、圆头锤等等,如果你买了一个,之后又发现你还需要另一个怎么办?多数人只想要一把锤子,所以我们推出了万能锤,可以当各种锤子使用。买者想想也是,那就买一把万能锤吧。店主说,No,万能锤已经被淘汰了。你想,万能锤虽然可以当各种锤子用,但它做什么活都没有专门用途的锤子好使。所以,我们开始卖锤子工厂,这样你可以随时制造最合适的锤子。买者说,但我并不想买个工厂……店主说,没错,所以它已经被淘汰了。我们研究发现,不是所有的用户都需要生产所有类型的锤子,所以我们开始卖锤子工厂设计图,这样用户可以根据自己的需要定制工厂。买者说,我猜这个也淘汰了吧?店主说,没错,我们研究发现,用户并不想自己建造一个工厂。于是我们推出了建造锤子工厂的工厂,来帮助用户建造锤子工厂……

三、殊途同归

    我们可以回想,在我们知道设计模式之前,难道我们就没有在用这些方法吗?之所以叫Pattern,就是因为它至少已经被重复运用三次以上,所以我们把它单独拿出来,赋予一个名字。所谓“新Pattern”就是一个悖论。Pattern的最大作用不是教人怎么做,因为面临同样问题时,大家多少会想出类似的解决方案;Pattern最大的作用,在于提供了一种共识、一套共通的术语,使开发人员间可以方便的交流一些复杂的系统概念。当然,有的人学了设计模式后会有眼前一亮的感觉,这是因为切身体验诸多问题的苦恼,突然得到解决之道,于是豁然开朗。而对有的人,没有体验过痛苦,只是听说Pattern是好的,于是就开始在代码里罗列Pattern。

    同理的,云计算是什么全新的东西吗?WebService是什么全新的东西吗?之前就没有类似的问题需要解决,就没有类似的解决方案吗?如果让你穿越到它们诞生前,从头解决这些分布式计算的问题,你会不会做出一个类似的解决方案?那么,又是什么使你能够发明这些新东西呢?是不是基本技能在特定问题下的一次应用呢?

    不管用哪种途径,用这套方法也好,那套方法也好,只靠自己琢磨也好,走对的话,都是通往同一条大道。不要把自己圈在一个小圈子里,圈子越小,越容易偏执。站得越高,看得越远,眼前的景色越壮丽,所谓的是非对错,不过是远处的一点而已。

    但是但是,现实中,不是所有的问题都是能由开发人员解决的,也不是所有的人都想要解决问题。流程、方法、思想、工具等,不管看起来再好,在不想解决问题的人面前,连个屁都不算。一个项目决定时的天时地利人和,已经八九成决定了项目的结局。当然,怨天尤人也没用,上天总是会给人几次机会的,机会到来时能不能抓得住,就看个人修为了。
作者:Nightmare 发表于2011-7-24 16:14:01 原文链接
阅读:13346 评论:130 查看评论

相关 [程序设计] 推荐:

最隐晦的程序设计指引

- Sirius - Dev in Nightmare
    俗话说,程序员半年不学新东西,就变奥特曼(out man,过时之人)了. IT行业可以说是变化最快的行业,每年都有大量的新概念、新术语、新技术被创造出来,在多数人还在一头雾水时,“更好的”替代品又被创造出来.     想当年静态类型系统是王道,谁要是搞点运行时动态绑定、用点VB什么的,经常会被鄙视.

高性能LAMP程序设计

- Kevin - 超群.com的博客
周六分享的PPT,一些比较common的大杂烩,看不到slides的同学在这里查看.

炮轰老谭的<<C程序设计>>

- 世博 - 博客园-首页原创精华区
  本人不学无术, 生财无方, 下作无品, 见园里一小女初学C#的文章都能上评论头条, 实在眼红得不知所谓, 于是写下此随笔, 绝不敢效仿hax, 只为吸引眼球而已, 读者诸君就当看小丑跳梁好了.. #188楼2011-09-27 03:27 | 陈梓瀚(vczh)      . 为了免去翻阅旧评论的痛苦,“62楼”不辞辛苦复制一遍winter-cn给的地址,你们一定要看啊…….

并发程序设计详解

- - 企业架构 - ITeye博客
Java性能优化系列之三--并发程序设计详解. 线程安全 设计模式 多线程 并行计算 并发.   (1)、Future-Callable模式:FutureTask类实现了Runnable接口,可以作为单独的线程运行,其Run方法中通过Sync内部类调用Callable接口,并维护Callable接口的返回值.

程序设计的 Top 10 做与不做

- 凯 - 博客园新闻频道
  今天来和大家分享两个很不错的程序设计「做」与「不做」列表. 首先,是 Andres Taylor (安缀斯‧泰勒)写的「Top 10 Things Ten Years of Professional Software DevelopmentHas Taught Me」,翻成中文就是「十年程序设计经验教我的十件事情」.

【测试调查】你是程序员还是程序设计师?

- - 外刊IT评论
二十年前,顶尖的程序员能将一个完整的应用放到一个64KB大小的 .COM文件里. 这是他们对可怜的因特尔80386电脑在编程上进行的最大挖掘. 这是因为,二十年前,电脑昂贵而程序员便宜. 那种理念已经不再有人欣赏,因为如今的市场形势发生了完全的颠覆. 如今,计算机便宜而程序员昂贵. 这是一个“程序员为先”的年代,不再需要考虑计算机的能力和限制,程序员的因素放到了第一位.

优秀程序设计的18大原则

- - 非技术 - ITeye博客
        1.避免重复原则(DRY - Don’t repeat yourself).   编程的最基本原则是避免重复. 在程序代码中总会有很多结构体,如循环、函数、类等等. 一旦你重复某个语句或概念,就会很容易形成一个抽象体.    2.抽象原则(Abstraction Principle ).

Hadoop 高级程序设计(三)---自定义Partition和Combiner

- - CSDN博客云计算推荐文章
Hadoop提供了缺省的Partition来完成map的输出向reduce分发处理. 有时也需要自定义partition来将相同key值的数据分发到同一个reduce处理,为了减少map过程输出的中间结果键值对的数量,降低网络数据通信开销,用户也可以自定制combiner过程. 自定制Partition过程:.

程序设计的一些基本原则

- - 编程语言 - ITeye博客
本文将对本人在程序设计方面的一些思考,逐步罗列在这里. note: 此类文章/书籍,多如牛毛. 对比它们,本文并不会出现什么新的概念、思路,都是人家说过的,总结过的. 如有侵权,请指出,我将给出引用. note: 它是我在工作中的一些问题/思考总结,附上一些实际的例子(经历过才更有感触). note::“想的太多,行动太少” 是大忌.

网易前端云课堂,JavaScript程序设计:JS调试

- - CSDN博客推荐文章
本节主要通过一个加法器,介绍JS如何调试. 计算器
. . 1,一般调试JS,打印信息有如下三种:. a,用alert,缺点是每次都弹框. b,用console.log,这个数据量小还可以.