跳到主要内容

简单之美

0 前言

禅宗 本来无一物, 顿悟 想入非非

积级反思,不断追求完美, 想象力和创造力的结合 + 软件开发思想比较完整

  1. 思想是解决一切问题的根本,
  2. 思想是明显灯,虽然有时也会变为桎梏
  3. 思想必须坚持成为习惯

Robert C Martin - Agile software development : Principles , Patterns , and Practices 软件是美的,简单的。

所谓混乱状态就是出现问题的时候,没有人知道如何做才是最好的。一套完整的思想体系可以解决。

1 无级生太级

创造性需要想象力。 获取知识,使用知识

简单、想象、文化

什么样的信息是有效的? 简洁、明确的思想表述,层次清晰的分类信息,令人信服的论证

所有的方法论都有上下文。

简单的原则,富于想象的精神,文化的视角来认识软件开发

1.1 创造力的根源

钱学森认为人有三种思维类型:逻辑思维、形象思维、灵感思维。 我们说,软件开发越来越需要创造力,越来越需要形象思维

我有一个有趣的想法:如果人们愿意定心敛神,细细体会熟视无睹的事物,一定可以得到超出想象的收获。 。什么是软件?本质上就是那些特定于CPU的二进制指令的集合。

在汇编语言中,数据结构的概念是很淡的,更不要说围绕数据结构展开的算法了。数据结构和算法的繁荣发生在比汇编语言高一级的编程语言中,例如C语言。 那些隐藏在幕后的技术,使我们可以仅仅关注于抽象的程序,而几乎不考虑硬件的问题。

C语言在一定程度上解决了人类在数学计算和逻辑推理上的抽象。 算法就是数学问题的求解过程。在使用C语言来实现一个软件系统时,逻辑思维占了绝对的比重。

企业级信息系统需要解决的是领域问题,而不单单是数学运算问题。 处理领域问题就像战场上的一个个战役,指挥官决策(问题求解)时,可以参考和依据的现象太复杂了,他必须借助面形的思维(经验、习惯以及形象思维)才能指挥队伍朝正确的方向前进。java 语言恰好是面形思维的好工具。(tomcat 源码带来的启发)

从 C 到 Java 隐喻式编程,Java 培养了我在软件领域的想象。 软件的美和价值在于创造,创造来源于想象。他需要一定的技能。

1.2 本质的把握

软件或软件开发的本质?艺术性的科学工作。

一个有趣的社会现象。 我们在这4年里学到了最重要的知识——做人和做事的方法

按照我们前面的说法,建立一个思想体系是最重要的。也就是说,只有在一个完整的上下文中思考才能真正解决问题。所以,我尝试用一条线索把上面的概念串联起来。

毫无目标的追逐会使有限的积累能力稀释,积累知识和技能的方法。 总之:思想体系没有建立,找不到建立思想体系的方法,以及不会应用思想体系来解决问题,我们就无法把握本质。也就是说只有在完整的上下文中才能解决问题。

网络连接的重要性,信息与计算能力的传递。 尽量使应用程序和容器隔离。

从 java rmi 到 web service , SOA 架构的基石。 SOA 确立了整合系统的思想, ESB 提供了准备就绪的服务。 根据以往经验,思考新的概念,解释,解释再解释,最后把这些新概念转化为思想体系。 这就是认知方法的本质。

1.3 简单的追求

作何时候都不要轻易丢弃一个非常简单的原则,作何时候都不要固执于一个具体的想法细节。 我们需要做的其实只有一件事,基于领域模型的计算。本质的就是简单的。 在我看来,企业应用软件很简单。它主要包括三个部分:一个领域模型,一组基于领域模型的计算,以及用来和用户交互的界面。这是一个基本的思路。 老实说,为了恪守简单的原则,我们应该逐渐进入细节。

在这个例子中,思考领域模型的时候不要立即开始考虑数据库的因素。可以做到吗?答案是,很多软件开发人员都做不到。他们总是忍不住会立即去考虑效率、领域模型中各元素的关系如何在数据库中的表达、OR Mapping工具在使用中的一些限制等。

实践中的复杂性是因为背景知识的缺乏,主要工作是收集信息,而信息量不是成功的关键,而是对他的应用。

越简单,越准确,越简单思路越清晰。

第二章 关于软件开发方法论的思考

以 CMM 和 敏捷为例 文化是方法论的基础,也是方法论的运行环境。割裂文化来实施方法论,就像建造空中楼阁。 你对场景故事的思考和感悟将是本书价值的重要组成部分。

2.1 方法论的实践场景

宗方 berry 孔如之 Ralph 【纯粹的技术人员】 Ken 孔如之的经理 王蓉 于伦 李小兵

Scrum 不是一种制度,而是软件开发的需要。它本身不解决任何问题,它有一些实践供我们参考,仅此而己。关键还是开发人员的主动性。 目标只有一个:如何提高开发人员的主动性。

2.2 CMM 的精髓

能力成熟度模型,对软件开发过程的关注。 当人们需要共同完成一件事情时,常常需要一些契约来规范人们的行为。在软件开发中,这些契约以过程的形式存在着。 为了使契约更加合理,软件开发组织需要对过程进行系统地思考和总结。这是一种持续的行为。另外,在软件开发实践中,过程会不断地得到优化。那些更合理的过程,会被保存下来并重复使用,最终成为知识资产的一部分。 在理想的情况下,CMM所关注的软件开发过程,应该是解决软件开发中各种混乱现象的一种理想方案。但是,在现实中,CMM往往被很多软件开发组织、甚至软件开发人员个人所排斥。

CMM 的价值

  • 系统性的,质量保证,配置管理,需求管理,项目管理,软件开发管理,同行评审,项目资源协调,人员培训,
  • 大量实践有效的模型
  • CMM 鼓励基于推荐的模型和活动来定义自己的软件开发过程。。CMM会依据规范来评估自定义的软件开发过程,换句话说,CMM是一个参考模型,它不要求软件开发组织严格遵守。CMM只是建议,在软件开发组织自定义的活动和CMM规范推荐的活动之间做一些映射。这些映射可以非常灵活。

我认识一位SEI认证的CMM评估师。在与他的交流中,我深刻地体会到,CMM其实是一个非常灵活的模型。事实上,只要有想象力和创造力,你定义的软件开发过程,将会完全适合你的组织现状和企业文化。你可以为不同类型的项目定制不同的过程,从而最大限度地提升工作效率。

报告存在的意义不在于应对质量检查,它的意义在于将来有可能从这些文档中提炼出有价值的观点。

2.2.2 成熟之路

我相信,在我们这个美丽的星球上,有不少值得尊敬的、成熟的软件开发组织。遗憾的是,我至今还未接触到它们。 不经历 CMM 很难体会到敏捷开发的意义。 所以,我更愿意把CMM看作是一条成熟之路。

2.3 敏捷软件开发的精髓

追求人的主动性,是智力活动密集性企业的最高目标。 追求主动性的原因在于,评价智力活动的成果是一件非常困难的事情,如果缺少了人的主动性,一切工作都会流于表面,组织的目标就会无法实现。

有一家顶尖的高科技企业,对员工采取军事化的管理,企业的规模和技术能力以惊人的速度在发展。这种现象超出了我的理解。军事化管理只有在狂热的理想主义支持下,才能激发人的主动性。狂热的理想主义在一个商业化企业中是无法持久的。

狂热的理想主义 提高软件开发人员的主动性有两种方法

  • 传播信仰
  • 建立一系列以人为本的的实践与方法集,用习惯和文化融合成员。敏捷软件开发致力于第二种方法。

Alistair cockBurn Agile software development: the corporation game 2th edition 一书中,从西方人的角度,对人的因素进行了分析。我总结了一下,在他看来,软件开发中的人主要有以下的缺陷: •人的沟通永远是不完全的,完全的沟通是没有必要的;
•人是古怪的;
•人们通常宁可保守地失败,也不冒险用不同的方式追求成功; •人们喜欢临时创造而不喜欢积累;
•人们不能始终如一。

在我看来,项目经理最重要的工作,应该是为软件开发提供服务。他是那个扫清路障的人、积极进言者、精神鼓舞者,而不是那个拿着时间表、冲着软件开发人员发火的人。要保证软件开发的进度,项目经理的频繁干预,不是一件好事。组织必须培养有责任、有追求的团队。这类团队,应该围绕着一位主刀医生角色的软件开发人员展开工作。

敏捷方法中的实践就像导演提供的剧本。在影片拍摄期间,导演总是会要求你完成那些设计好的动作和台词,从而快速进入角色。相比而言,敏捷方法中的“剧本”更加简单,它给人们留下了巨大的发挥空间,当然,与此同时,它也对人们的能力提出了较高的要求。

2.3.2 海岸灯塔

敏捷方法的支持者在理论上是理想主义者,在实践中是实用主义者。他们似乎指出了一个激动人心的方向,但是真正的终点其实还很远。遗憾的是,敏捷方法的可操作性是很差的。其原因在于,所有的一切都依赖于人本身。想象一下,我们强调对人的关注。可是,谁来对人关注?还是需要依赖某些人——具有特殊权力的人。在敏捷方法的游戏规则中,针对这些特权人本身并没有什么约束。他们可以关注人,可以懂得如何关注人;也可以不这么做,或是不懂得如何做。

英国人类学家泰勒认为,文化是一个复杂的总体,它包括知识、信仰、艺术、伦理道德、法律、风俗,以及作为社会成员的个人,通过学习获得任何其他能力和习惯。文化通常起源于个人和群体的习惯。当人们的习惯,融入到日常的生活中时,文化就产生了。

2.4 更好的软件开发方法

最好的开发方法就是最适合企业文化的开发方法。 企业文化: 经营经营者、管理者的价值观,组织成员的结构和背景 企业经营者和管理者的价值观,是评判组织成员价值(从组织的角度)的标准.在现实中,那些与价值观相左的贡献,常常会因为一些狭隘的认识而变得毫无意义。比方说,保守稳健的价值观会排斥激进创新,崇尚残酷竞争的价值观会排斥内敛独善等。

十几年前上大学的时候,我和哲学老师关系不错,经常一起聊天。有一次聊到了中庸之道。他告诉我,中庸,不是僵硬地居中于两个极端,而是一种非常动态和灵活的平衡。就像秤砣:秤砣在秤杆上来回移动,最终使重物与秤砣保持了平衡。换句话说,目标和能力是客观存在的两端,中庸之道就是这两者之间的平衡点。一旦找到了这个点,目标就容易实现了。

CMM为企业文化的建立贡献了自己的价值,它尝试建立一种科学的软件开发方法。这种尝试是开创性的,所以常常伴随着剧痛;换句话说,实施CMM,会使以往的开发方法受到全方位的挑战,各种显性或隐性的激烈对抗将层出不穷。 纵观历史,文化的形成,往往源自于严酷的制度。与之类似,在组织的软件开发方法形成之初,求助于制度也不失为一种办法。

事实上,软件开发方法是企业文化的集中反映。和社会文化不同(有着漫长的形成过程),企业文化(常常体现在软件开发方法中)需要快速形成。一种好的办法是,在兼容并蓄、博采众长的价值观基础上快速建立制度,然后用中庸之道进行调整。

什么样的调整呢?比方说,当规模变大时,我们应该在组织的软件开发方法中加入一些精细开发的思想。迄今为止,我还没有见到过精细开发的案例。这也许和我所能接触到的软件企业的规模有关。我接触到的很多软件开发组织,精细开发思想是很糟糕的。在这些企业中,一个软件开发人员往往要兼顾很多任务,而任务的指派基本上是随机的。 软件开发人员常常被视作没有任何差别(个性、技能、兴趣等)的资源。这种想法,无论从个人的角度来看还是从组织的角度来看,都是有问题的。

从个人的角度,粗犷分工不利于软件开发人员自身知识的积累。如果没有知识的积累,生产效率会变得极为低下。 从公司的角度,粗犷分工会造成大量重复投入的学习成本。

当随意安置的个人与小团队文化不适应的时候,同样会带来严重的生产效率问题。

2.4.2 聚焦

现实中的问题盘根错节。我们应该规划出一张路线图,用聚焦的眼光,逐个解决软件开发中的问题,并建立最适合自己的软件开发方法。

2.5 方法论的执行

2.5.1 关于执行

中国近代哲学史上有一种观点,即地理环境决定了文化差异。中西方的对比,农业文明与商业文明的差异。 中国是一个国土资源丰富的国家,农业是最重要的支柱产业。农业的特点是,居住地固定、很少迁徙。人们长期聚集在一起劳动和繁衍,这样的生活方式使家庭血缘关系成了社会中的主导关系。而家庭血缘关系中天然的长幼次序,又促进了家长制文化的形成。与中国不同,西方的希腊和罗马都是海岛国家,由于航海技术的成熟,商业贸易非常发达。人们通过航海,来往于不同的国家和文明。当时,来自各地的人聚居在一起,社会的主导关系,是商品交换中的利益关系而不是家庭血缘关系。人们通过大量人为建立的规则来保证自己利益。在这个过程中,逐步产生了民主和平的思想。

要求管理者承担保证执行效果的责任。要求承担执行效果的责任,可以促使管理者对方案的执行进行更加深入的思考,从而保证真正的执行成功。管理岗位不是一块可以坐下来休息的台阶,而是从另一个角度,观察并辅助方案执行成功的阵地。

•是源于个人意志还是众人意志?
•如果源于个人意志,是家长意志还是创作者意志?
•如果源于众人意志,是众人的主动追求还是众人的妥协产物? 要做到众人意志的统一是非常困难的。在软件开发实践中,总是会在众人意志不统一的情况下产生妥协的方案,这些妥协的方案往往会给软件开发组织带来无数潜在的问题。

2.5.2 约束与习惯

事实上,仅仅关注执行力是错误的。这就像头痛医头、脚痛医脚,缺乏解决问题的全局眼光。在执行力上关注越多,偏离执行的本质就越远。

软件开发方法不是解决执行问题的银弹。从约束到习惯的演变过程才是关键。你看,软件开发过程带来约束,长期的约束形成习惯,丰富的习惯促生文化,文化制造氛围,氛围产生最佳的执行效果。神奇的逻辑,约束最终将转变成自然!如果我们没有经历从约束到习惯、习惯到文化、文化到氛围的演变过程,就不可能在本质上提升执行效果。这就是我的解答。

我雇用那些成功交付过项目的人。

第 3 章 关于需求的思考

需求就像一束光的源点,失之毫厘,谬以千里。 首先,我们需要准确表达需求,术语和讲故事是两种好的辅助手段; 其次,我们要和客户一起推动需求的变化,需求变化不是成本的代名词,被动接受需求变化才是吞噬成本的罪魁祸首。

3.1 实践场景

“哈哈,”孔如之笑道:“如果我们帮助客户弄清楚他们的想法,做得了就做,如果成本太高,我们可以给一个详细的解释。大多数客户也是讲道理的,况且,TFC项目是个开口合同。”孔如之进一步解释:“如果我们不清楚客户的想法,那就惨了,他以为我们会做一些事,我们自己认为不在项目的范围内,客户会对我们的承诺和信用打问号的。”

需求故事的讲述技巧

3.2 需求开发

3.2.1 准确表达

最简单的句式和最简单的信息,是传递信息最准确的方式。 成本永远不是拒绝需求问题的理由。 领域术语是准确表达的关键。

开拓型项目,持续型项目 在实践中,这两种类型的项目碰到的需求问题有一些差别:在开拓型项目中,人们经常被客户的需求所淹没;在持续型项目中,人们经常因为领域问题上的理解差异,产生大量隐性的开发成本。

无论哪种类型的项目,都有一个共性。那就是,客户往往不能提出准确的需求(更不用说有系统地提出需求)。我认为,期望通过一两位专家就能把所有的需求传递给软件开发人员是不现实的。不现实的原因有三点: 首先,客户是一个群体,提出需求的人只是客户中的一小部分人; 其次,提出需求的客户并不能完整地考虑到所有的场景; 最后(也是最重要的),客户往往不能准确表达出自己的需求。

准确表达需求,需要特殊的技能和方法。理论上,提出需求的人必须经过专业的训练。 消除歧义取决于交流者的语境。准确表达的本质,是指信息的准确传递,而特定的领域知识是准确表达的基础。

最简单的句式和最简单的信息,是传递信息最准确的方法。 我一直认为,需要经过再解释的需求,不是一份合格的文档。它会带来歧义、返工和无法预料的后续成本。

要想解决需求问题,关键有两点。这两点都需要需求分析人员的努力。第一,需求分析人员应该使用客户提供的常识和素材,为客户提供他们可以理解的完整故事。事实上,单纯限制需求变化,只会演变为一场两败俱伤的战争;第二,需求分析人员要积累领域知识,提升对需求的预判能力,并把预判应用到软件实现中去。

  • 真正站在客户的立场上来考虑软件开发成本,是解决需求问题的最佳方法。这就是上面所说的第一个关键
  • 软件项目的成本绝大部分被用于软件实现。而只有好的实现(灵活性和扩展性),才能降低项目成本。

总而言之,在追求准确表达需求的过程中,软件开发组织要克服对需求不断修正的排斥心理。我们要学会站在客户的立场, 成本永远不是拒绝解决需求问题的理由。

3.2.2 信息传递

如果不注意信息表达方式的转换,例如,在需求分析时混杂着领域知识、生活常识、软件术语等,就很容易给软件开发人员(信息接收者)带来困惑。

一种理想的做法是,我们应该在需求分析阶段准备两份文档。一份是使用客户的术语来表达客户的故事,另一份是使用软件术语表达软件实现的故事。前者类似于“设计”工作,后者类似于“编程”工作。

所以我们的结论是,需求分析需要用到不同领域的术语。术语是准确表达的关键。要想掌握术语,必须经过长期的学习和持续的关注。

use case 用自然语言来捕捉需求。 解释会导致歧义:解释越多,歧义性越大。要提高自然语言的准确性,有两个办法:一个办法是,使用常识性的自然语言(包含领域术语)来减少二次解释;另一个办法是,调整故事的讲述方式(简单句式、层次递进)。 对于需求分析人员来说,最重要的技能并不在于领域知识(尽管也很重要),而在于讲述需求故事的能力。我们要求的讲故事方式,有两个特点。第一,是结构简单;第二,是层次递进。

3.3 需求管理 如《易经》应对变化之道 需求的变化不能由客户来驱动。被动地响应需求的变化,将会付出最大的成本。

敏捷方法有所不同:它提倡拥抱变化;要求客户更频繁地参与软件开发过程;通过更频繁地交付产品,帮助客户理解并调整自己的需求;拒绝过度设计,期望刚刚好完成客户的需求;期望持续重构,使产品在逐渐符合客户需求的过程中渐进地完善。然而,以上的这些方法,都没有抓住解决需求变化问题的本质。

需求分析的目的是使客户明白自己的需要,而不是单纯地限定需求的范围。我们需要考虑商务上的因素,但是很多人也许并不清楚,商务上,或者说软件开发上的成本,到底产生在何处?如果我说,成本与需求的范围关系不大,你同意吗? 细节而不是范围对实现的时间产生非常大的影响。

让客户明白自己的需要,离不开需求分析人员的主动性。

我们应该主动促使需求变化的发生,而且越早越好。被动接受需求变化才是最大的风险。 问题(软件开发成本)的关键,在于你的技术能力,而不是需求变化。主动出击一切才会在掌控中。 •用户对于自己的理解更加清晰,将来变化的可能性会有效地衰减。
•时刻关注需求的变化,为软件实现提供了更多影响设计的元素,从而使软件开发成本受到了控制。 •积极面对需求变化,而不是逃避,会更有利于需求分析团队的成熟。
•使客户强烈地感受到合作立场,生意就是生意,但你是个好的伙伴。

4 关于软件架构设计的思考

软件架构师在软件开发中的角色就如同主刀医生在一次外科手术中的角色,不确立这一点,软件开发的正常化就无从谈起。 当人们设计软件时,通常是在隐喻的基础上直接想象系统的运行状况,随着想象的细节化,然后才会有各种抽象的产生。可是,这个阶段没有被任何软件设计的方法论所关注。

4.1 架构设计的实践场景

“软件测试在项目开始的时候就开始了。要参与需求分析、编写测试用例,要向软件开发人员介绍测试中发现的问题,以帮助他们在开发时避免发生类似的问题。其实,所有的人,不管是从事哪种任务,都是贯穿整个开发周期的。这才是专业的做法。” 精确的认务分工 越是专业,就会考虑得越全面,就会发现要做的事越饱满。不精细,就不可能做到专业;不专业,就不可能有成熟的产品。

10个AD中没有一个展现出了纵观全局的能力,他们中的大多数都有一定的开发经验,但是大多数也都拘泥于技术细节,对于软件的整体认识说不出个所以然。只有一个AD,林峰,给他留下了一些印象。 什么才是正确的架构师,孔如之心里有一个非常清晰的标准:那就是完整的思想体系、全面的技术能力、较强的沟通能力。

10 个人的团队是一个最佳规模的软件开发项目团队。在这种规模的团队中,你才能充分了解每一个人,充分发挥每一个人的智慧,还有——充分沟通。 有一个和需求故事对应的层,这个层完全由接口组成,他代表了故事的结构和线索,他将使我们的程序结构非常清晰。

4.2 软件架构的本质

“一件事情,如果想清楚了,做起来就会很容易。架构设计就是想清楚这件事。”。而架构设计就是想清楚这件事。 有两个技巧可以帮助人们来表达一些比较复杂的设计。一个是由简到繁、纵向渐进式表述;另一个是多角度、横向侧重式表述。 从系统的角度,页面流转的角度,物理部署的角度。

每一个观察软件系统的角度,都会产生一张软件架构视图。将所有的视图结合起来,就能获得对将要构造的软件系统的全面认识。 军事上的战役行动计划在任何教科书上都是找不到标准答案,。每一项行动都是战役决策者根据战场上瞬息万变的情况做出的决定。有时候,影响战役格局的可能只是一个看似微不足道的细节,例如,准确的情报或者无法预报的恶劣天气。软件架构也是如此。在构架软件系统时,一个细节上的失误,可能会导致巨大的软件开发成本。

4.3 软件架构的设计

当然,每个人对于保守的认识是不同的。拿我来说,我极度反感动态语言,以及在一个非常受限的“小笼子”里折腾花里胡哨的界面。从这一点上说,我是保守的。但我也有反思、创新的一面,比如,我认为HTML早该淘汰了,纯粹是商业的原因才让这个历史产物生存到今天。浏览器需要补充新鲜血液,我估计这一天很快就要到来。

以 applet 编写为例的架构设计。 模式化的想象使人们的思维变得清晰和具体。这也是所有架构的本质。 或许,我们应该重新审视POJO(Plain Old Java Object)的价值。在应用系统架构中,POJO的使用是很重要的。只有使用PLOJO,我们才能使业务逻辑与框架解耦,我们才能使业务逻辑成为一项独立发展的知识资产。

  • Java example
  • 框架的本质是约束
  • 架构和框架。完全不同的两种东西。

Business Process Man-agement框架 和 SOA 架构 隐喻的价值 隐喻的本质就是想象,想象的前提基于隐喻。 隐喻的目标是抽象

•有完整的隐喻; •使用统一的对象模型; •对框架的使用者做出了约束; •为应用提供了服务。 如果你尝试设计框架,上述的特点是一定要充分考虑的。这些特点(原则)可以帮助你在设计时保持清醒的认识,并且永远走在正确的道路上。还有一点也很重要,那就是简化思路,不要去想10分钟内无法理解的事情。在企业应用中,那些无法理解的事情通常不是因为其本身有多么复杂,而是结构上的混乱造成的。

设计模式是一种经典的隐喻。

架构模式

架构模式是对架构的进一步抽象。由于抽象进入了较高的层次,架构模式逐渐成为软件行业中的语言元素。

架构师的素质

诚实、想象力(形象思维)、逻辑思维、常识、理想主义、兼容并蓄、反思精神

5 关于软件实现的思考

我们希望软件生产的参与者是简单的、快乐的、积极的、负责的。为了做到这些,我们还需要制度和文化。软件生产是一项系统工程,这需要我们不断完善自己的思想体系。机械地运用某些技术方案是无法真正解决问题的。

5.1 实践场景

职场上有一个潜规则,就是尽量不形成文字。所以,很多人都不喜欢通过邮件来表达自己的观点,而会议是一个很好的替代品。在会议上,大家可以天马行空、热烈讨论,不需要成熟的观点,不需要明确的想法。最终的决议可能都成了大家的意见。作为会议的组织者,于伦可以轻松地释放责任的压力。 可是最近,于伦发现气氛有点变了。孔如之一直在强调责任问题,

当领域模型变得混乱的时候(这种情况太常见了,我们总是可以看到:软件开发人员会根据需要任意修改模型;或者,由于建模不当,在查找一个信息时要使用10个以上的对象关系),软件实现也变得混乱了。如果软件实现被建立在随意变化的模型上,它们就不可能成为长期有价值的知识。在这种情况下,软件开发就像被挟持在一艘失去控制的航船上,在一条颠簸的航线上渐行渐远。

5.2 模型设计

领域模型

静态模型,动态模型。 [静态信息,动态信息]

如果一定要区分,那么领域模型中的对象应该有两种:一种是只具有静态信息的对象,也就是通常所说的实体对象,或者说是Martin Fowler 所谓的贫血对象;一种是同时具有静态和动态信息的对象,它尝试描述驱动静态信息状态变化的数学规律,例如,驾驶行为,它可以使摩托车、轿车、飞机、轮船等的状态发生变化。

5.2.2 计算模型

https://www.joyent.com/ 22名员工就可以支撑一个全球性的基础设施服务,这让人感到非常惊讶。 理解计算模型是很重要的。这决定了我们是否可以正确地使用一些计算过程,并从中得到有价值的回报。 计算模型并没有包含精确的定义和严格的逻辑推理,它通常是一些架构图和自然语言的描述。原因很简单,业界还没有公认的、成熟的能表达计算模型(基于软件和硬件)的数学抽象。这也是为什么我们接受的往往是一些关于计算模型的概念,而对于这些概念的不同理解总是会带来争执的声音。在企业应用软件开发中,一般不会去建立新的计算模型。我们需要做的是,往往是从很多成熟有效的计算模型中选择最适合的那一个。例如,客户机服务器计算模型、分布式计算模型、网格计算模型、云计算模型。

5.3 软件开发

写给新手

王衍 中科大少年班毕业的物理学博士,软件天才 成熟的设计风范

我发现提升技能的方式大概有两种: 涉猎惊人的细节,不停的总结 编程语言是一种工具,克服面对未知领域的畏惧。方法论是解决问题的关键。

当这位软件架构师向我们介绍他的设计内容时,我大不以为然。为什么呢?因为设计图中都是一些明摆着的事情,太简单了,一个Actor连到一个个椭圆上(登录、下订单等),我开始重新审视建模工具,并且认识到了自己的错误。那些看上去简单的用例图,其实是极具价值的。 •问题的解决方案不是唯一的; •方法论是解决问题的关键; •过程的控制是实现目标的保证; •知识资产不在人的头脑中,而在某种形式的持久化信息载体中。

团队生活,什么是团队? 共同的目标,共同的价值观,沟通顺畅,相互促进

他们的快乐不是建立在编程的本质上,而是建立在好奇和炫耀 快乐就在开发过程的细节中。

5.3.2 掌握编程

可是,在实践中,为什么有不少程序员在使用某些编程语言时感到比较吃力呢?问题不是来自编程语言本身,而是使用编程语言的环境以及应用编程语言的领域。 一般来说,编程环境包含了以下内容: •库; •依赖; •编译; •集成开发环境中的配置,项目结构和调试; •部署和执行。 看上去,我们总是有很多编程方面的知识需要去学习,但是,我们更应该学习的其实是学习方法。经验告诉我,从编程思想入手,寻找一条简单的线索并持续围绕这条线索积累知识,是一种好的学习方法。如果思想不求进步,一切随缘,则很容易被知识的海洋淹没。

实际上,我的编程生涯并非一帆风顺。如果上天能给我重新来过的机会,我一定会尝试着这样做:

  1. 充满信心
  2. 参考书 + 导师
  3. 领域知识

模式是可以重用的解决方案。有点像功夫的套路。 1987年,肯特·贝克和沃德·坎宁安,把克里斯托佛·亚历山大在建筑设计领域里的模式思想引入到了软件开发领域。从此,模式思想开始在一个小范围内发展和成熟起来了。1995年,GoF推出了《设计模式》一书。模式思想终于成为了软件领域中的一个重要思想,无数人从中获益。

所有的人造产物都建立在经验之上。 1995年,Andrew Koenig提出了反面模式(anti-pattern,有人译作“反模式”,但这种译法容易带来误解)的概念。 什么是反面模式: •行动、过程和结构中的一些重复出现的初看是有益的、但最终得不偿失的模式。
•在实践中证明且可重复的清晰记录的重构方案。

我们来看看一些编程中常见的反面模式:
•意外的复杂度(Accidental Complexity):向一个方案中引入不必要的复杂度。
•积累再开火(Accumulate and fire):通过一系列全局变量设置函数的参数。
•在远处行动(Action at distance):意料之外的在系统分离的部分之间迭代。
•盲目信任(Blind faith):缺乏对bugfix或子函数返回值的正确性检查。
•船锚(Boat anchor):在系统中保留无用的部分。
•Bug磁铁(Bug magnet):指很少被调用以致最容易引起错误的代码,或易出错的构造或实践。
•忙循环(Busy spin):在等待的时候不断占用CPU,通常是因为采用了重复检查而不是适当的消息机制。
•缓存失败(Caching Failure):错误被修正后忘记把错误标志复位。
•货运崇拜编程(Cargo Cult Programming):在不理解的情况下就使用模式和方法。
•检查类型而不是接口(Checking type instead of interface):仅是需要接口符合条件的情况下,却检查对象是否为某个特定类型,可能导致空子类失败。 •代码动力(Code momentum):过于限制系统的一些部分,因为在其他部分反复对这部分的内容做出假设。
•靠异常编程(Coding by exception):当有特例被发现时才添加新代码去解决。
•隐藏错误(Error hiding):在显示给用户之前捕捉到出错信息,要么什么都不显示,要么显示无意义的信息。
•异常处理(Exception handling):使用编程语言的错误处理系统实现平常的编程逻辑。
•硬编码(Hard code):在实现过程中对系统环境作假设。
•熔岩流(Lava flow):保留不想要的(冗余的或是低质量的)代码,仅因为除去这些代码的代价太高或是会带来不可预期的结果。
•loop-switch序列(Loop-switch sequence)使用循环结构来编写连续步骤而不是switch语句。
•魔幻数字(Magic numbers):在算法里直接使用数字,而不解释含义。
•魔幻字符串(Magic strings):直接在代码里使用常量字符串,例如用来比较,或是作为事件代码。
•猴子工作(Monkey work):指在一些代码复用性或设计上很差的项目中的反复出现的支持性代码。通常会被避免或是匆忙完成,因此易于出错,有可能会很快变为Bug磁铁。 •Packratting:由于长时间不及时释放动态分配的内存而消耗了过量的内存。
•类似保护(Parallel protectionism):随着代码变得复杂和脆弱,很容易就克隆出一个类似的结构,而不是直接往现有的结构中添加一些琐碎的属性。 •巧合编程(Programming by accident):尝试用试验或出错的方式解决问题,有时是因为很烂的文档或一开始就没把东西搞清楚。
•馄饨代码(Ravioli code):系统中有许多对象都是松散连接的。
•软代码(Soft code):在配置文件里保存业务逻辑而不是在代码中。
•面条代码(Spaghetti code):指那些结构上完全不可理解的系统,尤其是因为误用代码结构。
•棉花里放羊毛(Wrapping wool in cotton):常见的情况是某些类的方法只有一行,就是调用框架的代码,而没有任何其他有用的抽象。 •还有一些项目管理上的反面模式,也很有趣。
•死亡征途(Death March):除了CEO,每个人都知道这个项目会完蛋。但是真相却被隐瞒下来,直到大限来临。
•拖后腿的无知(Heel Dragging Blindness):项目经理的无知拖了后腿。出于某些动机,员工趋向于减少努力来延长项目时限。例如,他们是按时间(而非结果)付费,又没有能顺利转移过去的后续项目。没有人对反面模式进行积极的推广,可是,绝大多数软件开发组织都殊途同归地使用了这些反面模式。这难道是人类的本能吗?

好的程序结构: •使用统一的领域模型; •使用高内聚低耦合的组件模型; •方法体短小精炼; •方法体内的控制流尽量简化; •控制流集中处理,如使用控制流管理器(规则管理器或流程管理器)。

单元测试和工具

BRMS: business rules management system 工具不应该在我们做的事情上留下任何影子。

重构是个伪命题。不要寄希望于重构,一次就做好。

5.4 负责制度 责任,权利,利益,是保证人发挥的关键。 负责制度对软件决策有着深刻影响,而正确有效的决策是软件质量的保证。

5.5 软件决策 决策者除了专业技术外和决策经验外,还需要有简化问题的能力。

例如,可移植性原则。要保证可移植性,最简单有效的方案是,让系统的业务逻辑与一切平台以及第三方工具和框架无关。选择的平台和框架都要基于这个标准。如果不能基于这个标准,就必须设计一套独立的接口,断绝业务逻辑与外部一切不必要的依赖关系。

软件开发和外科手术。 软件开发是一个不成熟的行业,不成熟的原因之一就是缺少决策机制。

构成毛泽东政治哲学的核心观点是冲突或矛盾,以及由此引起的变化。在毛泽东的政治著作中,他所论及的每一个重大的政治问题都是以冲突和变化概念为基础的。在他看来,政治领域里各个方面合乎规律的、恒常的冲突和变化,与自然界的冲突和变化的情形是相同的。由于他的认识论是建立在上述核心观念基础之上的,因此,他不只把他的政治理论看成是这种冲突和变化观点的阐发,而且看成是这一观点的例证,从而服从于支配着自然界和政治现象的同一发展规律。[美]约翰·布莱恩·斯塔尔《毛泽东的政治哲学:论冲突》

有时想想觉得很有趣。通常,非专业的人都不敢去干涉一个专业的手术。可是软件开发不同:每个人都希望进行决策,而每个人也都很幸运,因为没有人会当场死在“手术台”上!

5.6 质量保证 CMM 中的质量保证与众不同。 软件质量保证是 CMM 中应用最广泛的规范。 CMM 将软件质量保证提前,更早的参与软件生产的过程中。过程控制是目标的保证。 CMM 只是带来了软件开发过程中的可视性。 重要的不是问题,而是反思为什么会有 GAP , 如何修复这个 gap 其实不是这样的。软件质量真的不在过程控制所能影响的范畴中。

坦率地说,CMM规范中的软件质量保证活动是我最反感的地方。这种质量保证活动的目标是为了实现项目进行的可视性(参见CMM规范),这使我觉得既荒唐又可笑。试想,当一个主刀医生正在进行外科手术的时候,旁边有个人不断地纠正他持刀的手势、切口的大小,同时要求他汇报手术的进展状况,这不是很荒唐吗?

孔如之把质量保证的认识提到了一个新的高度。他认为,质量保证的目标不仅仅是给出计划与实际情况的差异,还要帮助团队分析差异产生的原因并且找到解决办法。仅仅给出计划与实际情况的差异,不需要人的智力活动。

谁可以带来高质量的软件? 开发人员。 如何提高开发人员带来高质量的软件?揽提升开发人员的主观能动性,技能。 如何提升开发人员的主观能动性,技能? 文化

敏捷开发在质量保证上更加实际,他没有明确的质量保证活动,但质量保证贯穿在整个实践过程。(测试驱动,结对编程,持续重构)

6 关于软件测试的思考

软件测试是一种破坏,只有破坏推动了建设才是有意义的。 几乎所有的问题都可以在软件生产过程中解决,这说明了软件生产是不完整的,而不能说明性能测试是成功的。。换句话说,如果在下一次的性能测试过程中,我们仍然碰到同样的问题,那么从软件开发本身来说(非商业性的因素),这次性能测试几乎没有任何意义。 没有设计就无所谓测试。

王蓉也觉得自己有点成熟过头了。也许就是因为成熟,她对同龄人,甚至比自己大几岁的男孩子都没有一点交往的兴趣。刚来上海的时候,她曾经交往过几个这样的男孩子,当时她对白领啊、IT工程师啊、外企啊,还充满好奇和羡慕。可是不久她就明白了。这些男孩子听上去也算高薪一族,可是和他们在一起的时候,也只能住住出租房,只能逛逛七浦路,只能谈谈5年后,只能想想中大奖。因为要攒钱买房,他们下班后的最大活动,无非就是上上网打打游戏看看A片,无聊透顶。有一个本地的男孩子还不错,因为没有攒钱买房的问题,两个人总算可以出去透透气,在金茂大厦吃顿饭,在衡山路上泡泡吧。后来,因为这个男孩子的父母不同意他和外地人交往,两个人分手了。分手的时候,那个男孩子泪流满面,王蓉却一点感觉都没有。“为什么我总是碰到没有长大的人。”她在心里对自己说。

低效的测试过程和极低的自动化水平 软件测试能力是软件开发组织技术能力的一个缩影。 功能性,易用性,稳定性,安全性,移植性

6.1 实践场景

孔如之很清楚,无论你在工作的过程中作出了多大的努力和改善,如果没有一个好的结果,一切都是白费。没有人会关心过程,没有人会关注问题产生的原因,特别是那些不落地的管理人员,他们永远只根据报告作判断。

6.2 软件测试的本质

软件测试的定义中有四个关键词:规定的条件、发现错误、衡量品质、是否满足设计要求。事实上,任何需要进行测试的产品都必须工作在这四个关键词之下。

我认为,有些品质是软件测试无法检测的。例如,程序结构。程序结构在软件品质的衡量中应该占有重要的地位,这一点却无法通过软件测试来进行检测。事实上,要保证程序结构的品质,程序员的技能和主动性也是一个关键因素。

软件测试一度被认为是编程能力偏低的员工的工作,直到今天,仍然有许多公司把优秀的人才放在编码上,也有更多公司让优秀的人才进行设计,可是很少有公司让优秀的人才进行测试工作。实际的软件工程实践证明,让对软件思想有深刻理解的工程师进行软件测试,可以大幅度的提高软件质量。

你见过在需求分析阶段就启动的测试计划吗?你见过没有软件开发人员协作就编写的测试用例吗?你见过软件测试方面的知识资产吗?你见过稳定性测试的工作清单吗?你见过硬盘和内存空间不足时系统是如何表现吗?你见过网络中断时关键数据是如何保存的吗?说实话,我很少见过。在这种情况下,软件测试对提升软件品质的作用极其有限。软件测试能力是软件开发组织技术能力的一个缩影。

在我看来,不进行设计就期望软件具有这些特性是很荒唐的。软件没有这么智能。

6.3 测试的本质

软件测试是一种破坏 我赞同敏捷方法提倡的测试驱动。这种敏捷测试方法,我称之为“可行性测试”,就像对汽车进行动力学测试一样,它是软件生产的一个组成部分,是由软件的设计者和实现者共同完成的。“可行性测试”可以保证软件在某些情况下是可以工作的,但是不保证软件在更多的情况下可以工作。

软件测试与敏捷 软件的测试原则: 聚焦、 破坏者往往不会参与系统的建设,他们对于系统的了解是不全面的。因此,当破坏者展开攻击时,他们会聚焦于系统中的某一个点。他们会寻找这个点上的逻辑缺陷,并结合自己对系统的理解,展开各种推理和攻击。 积累 【软件测试中的积累应用到构建中去,将不再需要测试】、 自动化、

目标一致、

我们不要忘了软件测试的另一项使命——帮助软件获得更强的生存能力。 我们在前面已经提到过这个观点。基于这个观点,所有的测试手段(存在于企业资产库中)都应该是公开的,而不应该是“独门暗器”。理想的情况下,在软件生产时,开发人员就已经对这些攻击的可能性进行了考虑、设计、实现和验证(我把软件实现中的这种验证称之为“可行性测试”)。就测试手段来说,软件开发人员和测试人员所使用的没有什么不同。区别在于,软件测试人员尝试覆盖更多的逻辑路径。

6.4 一个典型破坏:性能测试

这是软件设计和实现无法解决的问题吗?不。 这是软件设计和实现无法解决的问题吗?不。 这是软件设计和实现无法解决的问题吗?不。

保持一个简单的思路,注意经验知识的积累,不断地在解释中提高认识。

7 关于团队的思考

阅读一本书时,关注作都自己的观点,而不是引述。引述都是有上下文的。 以湘江战役和红军长征,蒋介石围缴为例。 利益冲突,造成思想上的不一致,最终导致团队的分崩离析。

7.1 团队的实践场景

奖金问题为例

7.2 湘江战役

在中央红军第五次“反围剿”陷入困境的时候,白崇禧判断出了红军即将进行战略转移的意图。 拥有优势的兵力资源,拥有周密的“围剿”计划,拥有白崇禧这样的优秀人才,胜利看上去势在必得。可是结果却事与愿违,问题出在哪里呢? 有了看似周密的计划和看似强大的团队,胜利之势却在转眼间化为乌有。问题到底出在哪里呢?我认为,除了宏观意识形态 上的优劣(代表人民利益的思想总是更先进,蒋介石首先是从思想上败给了毛泽东)之外,一个重要的原因在于,蒋介石团队成员的利益之间存在根本性的冲突,这种冲突造成团队成员间思想上的不统一,并最终使团队的力量分崩离析。

7.3 团队建设

一个成功的团队,其成员在思想上是高度兼容(相互认同)的。从价值观到软件开发思想。

思想上的保证是第一位,即文化。 价值观: 理性、美、经济、教育、政治、社会、宗教 真正具有创造力的人,并没有什么标准的性格。所以,与其关注团队成员的个性,不如关注团队成员间的化学反应。

误区一:团队利益高于一切过分推崇这一论调,会导致两个弊端。一个是容易滋生帮派主义,一个是容易导致个体的利益被忽视和践踏。 误区二:团队内部不能有竞争没有竞争机制,容易导致以团队精神为名义的大锅饭,从而使团队成员的创造性得不到充分发挥,使团队失去活力。 误区三:团队内部皆兄弟过于追求亲和力和人情味,会导致管理制度的失效。 误区四:牺牲“小我”换“大我”过分强调团队精神,容易导致团队成员的个性创造和个性发挥被扭曲和湮没。

组织、团队、个人 组织文化可以多源,团队需要价值观高度统一, 努力推动轩团队的思想交流。 考察一个团队成员: 基本技能的要求,开放的心态

如何组建团队:

  • 统一的价值观和软件开发思想
  • 精炼的团队
  • 分工和专业化【分工是为了更好的调配团队内的知识结构,也是提高团队效率的根源,专业化的积累】

团队建设的现实问题

基层、中层、高层、 不同的角色

  • 利益分配问题 (本质是理想和公平问题)
  • 两个现实的问题: 只信任服务时间长的员工、忽视员工的成长
  • 企业在实现经营目标的过程中,需要的是人的才能。如何在一段时期内持续而充分地发挥人的才能,并为企业目标做出个人的最大贡献,是企业经营者的首要任务。
  • 在这个过程中,人的情感对于企业目标的贡献既微妙又复杂。因此,企业经营者应该站在更广阔的社会平台上来看待这个问题。简单来说,就是关注人才的贡献,而不是人才本身。

德鲁克认为,企业的利润动机是无关紧要的。从企业外部来看,似乎是这样的。但是,我们在这里谈论企业的内部建设。从团队成员的角度来看,企业的动机以及受此动机影响的企业内部行为却是一件需要关注的事情。按照德鲁克的说法,利润是企业经营活动的检验标准,而不是企业经营活动的目标。企业的目标应该超越企业本身,存在于社会之中。

企业在实现经营目标的过程中,需要的是人的才能。如何在一段时期内持续而充分地发挥人的才能,并为企业目标做出个人的最大贡献,是企业经营者的首要任务。

7.4 团队管理

人、稳定、文化

尽管在客观上,人员流动会为企业的创新带来不少好处,但是在主观上,这不是我提倡的一种团队建设策略。我希望团队是稳定的和具有自我提升能力的。 稳定的团队会为企业的生产目标做出更多的贡献,这就是所谓的——“稳定的价值”。

沟通不畅的原因:人们在知识和经验上的差异以及在利益上的冲突。

  • 在我们生活的这个时代,每个人都拥有发言权,每个人都有自我选择的权利。这种自我意识的觉醒得益于知识的普及。有时候我在想,自我意识的觉醒是一件好事,但在觉醒的过程中,由于文化沉淀的滞后性,往往也会带来一些问题。在我看来,如果解决了这些问题,知识的力量将会更加强大。 出发点的不同(本质上是思想认识问题)会导致思想认识上的差距,最终偏离方向。

Scrum是为软件开发人员服务的方法集,是为了帮助一群具有主动性的软件开发人员解决在工作的方式方法上的问题。这群人期望沟通,但是缺少合适的沟通形式;这群人期望了解自己的工作状况,但是缺少合适的视图;这群人期望分解自己的工作任务,但是缺少团队的支持。

我认为,好的团队管理首先是建立一种正确的人才选拔和培养机制。 职业发展路线图 人才选拔

8 关于项目管理的思索

混沌理论

8.1 实践场景

8.2 项目管理的本质

项目管理是服务,不是管控 计划的适应性面非预见性

我一直认为,好的项目管理,对于项目的成功并没有多少关键性的推动作用(有一定的推动作用),但是差的项目管理,对于项目的失败却要负一种关键性的责任(会输掉有赢面的牌局)。这种想法和传统的对于项目管理的认识不大一样。

但实际上,一手好牌才是你最应该追逐的。它会使你的获胜概率有实质性的提高,而不用每一局都玩心跳。

项目管理试图获得对5个变量的控制:
•时间,
•成本,
•质量,
•范围,
•风险。

把项目管理和软件开发工作清晰地分开,是一种最佳的实践。 在我看来,项目管理关注的应该是项目进行过程中的各种信息,需要进行管理的也是这些信息,通过信息的管理来间接影响技术工作,而不是直接干涉技术工作本身。另外,那些信息是经过项目管理人员设计的“传感器”获得的,而不是强制软件开发人员停下本职工作来进行整理和汇报而获得。

8.3 项目经理

项目经理,

马仔型项目经理 这种类型的项目经理基本上没有任何管理方面的思想。他们的工作就是执行上级管理者一些非技术性的想法。上级管理者坐在远离软件开发现场的办公室中,总是希望看到详细的项目进度报告、希望看到产品质量报告、希望看到风险受控的报告、希望看到项目计划被严格执行、希望看到项目成员承受着工作的压力、希望看到项目成员工作热情高涨、希望看到自己正在关心的一切。

社交型项目经理 这种类型的项目经理非常注重人的因素。他们在进行项目中的各种决策时,会考虑各方的意见和利益;他们总是进行多方协调,最终往往形成一些妥协的方案。

万能型项目经理 这种类型的项目经理拥有较强的个人经验和能力。他们对项目中的问题事必躬亲。几乎所有的解决方案,都打上了他们自己的烙印。

智慧型项目管理 这种类型的项目经理掌握了丰富的项目管理知识。他们会使用一些管理技巧来改进项目士气和团队精神。例如,AlistairCockBurn在Agile Software Development: The Cooperative Game一书中提到一个故事,“在某些时候,他们会把自己置于一些社交险境(冒险采用新思想,或者承认无知)当中,当他们受到批评时,就会得到来自团队的支持。”智慧型项目经理往往可以在短期内对建设一个好的项目团队做出贡献。但从长期来看,使用管理技巧不是解决项目管理问题的根本方法。

8.4 计划的本质

预见事物的发展。动态适应。 混沌理论认为,在一个动态的系统中,即使初始条件发生了十分微小的变化,但是,经过不断放大,对其未来状态会造成极其巨大的差别。

我们说: 首先,建立在猜测基础上的计划是没有任何预见性的; 其次,完全基于科学计算产生的计划(拉普拉斯的决定论是可预测理论)不适用于动态系统; 再次,混沌理论提供了一种兼具质性思考与量化分析的方法,它建议用整体、连续的数据关系对未来进行预测; 最后,从混沌中理出规则存在着可能性,但对于软件开发这类工程没有实用性。

8.5 风险的问题

钱学森先生一直在强调系统工程,我非常赞同。我对系统工程的理解是,很多问题的解决,都需要放在一个系统的环境中来考量。如果割裂事物之间的关联,头痛医头、脚痛医脚,就不能真正地解决问题。

事实上,在软件开发过程中,最大的风险只有人。同样的风险,由不同的人来处理,得到的结果也可能会大不相同。遗憾的是,关于人的问题,不是项目上可以解决的。

对于项目管理人员来说,你需要考虑的应该是风险服务(响应项目成员的请求),而不要把风险预防和控制作为你的主要工作内容。

8.6 管理的境界

我认为,对软件开发来说,管理的最高境界就是简单。 简单不是来自愚民思想,也不是来自“道法自然”,而是来自单纯、自由和坦率的精神。这种精神可以在技术领域中找到。

9 软件维护的思考

对于软件维护的考虑要从设计阶段就开始规划,这是解决维护问题的根源。未雨绸缪,才能决胜千里。 另外一个重要的思想,就是毫不妥协地解决历史遗留问题。很多人被这种遗留问题束缚了手脚和头脑,这是一种巨大的浪费。当你无法承受软件系统的维护费用大于开发费用的时候,

9.2 软件维护的本质

维护的内容:修BUG,加功能,做升级。

Eclipse 最初的决定之一是:“We will eat our own dog food”,即Eclipse团队要使用Eclipse进行Eclipse的开发。

我们说,软件维护(除了修复Bug之外)的本质是对现有系统的改造,而组件化和系统的可扩展性是使这种改造得以轻松进行的主要方法。我想不出还有第二种方法,可以从根本上解决软件维护的问题。基于这种想法,在软件维护阶段,坚决地展开重构是一个基本的思路。

人生就是这样,痛苦往往来自明确的目标,而幸福往往来自没有选择的生活。 “我会留在上海的。”孔如之用力搂了一下王蓉的腰。这个动作泄露了他的谎言。 我见到过很多扩展性极差的软件系统。它们受困于软件维护,一年、两年、五年,甚至更长的时间,无数的开发成本投入其中,可是毫无成效。在软件维护过程中,他们不断地积累(并应用)错误的经验,从而使软件系统变得越来越难以维护。为什么会这样呢?道理很简单,他们没有建立重构的思想,只是停留在修补和对历史遗留问题的妥协上,这使他们的努力和投入变得毫无意义。

9.3 组件化开发

我认为,软件的设计方向和设计的主体结构必须足够好,换句话说,方向和主体结构至少要保持5年以上的稳定,想想Linux、Windows、Eclipse吧。 要想做到足够好,就必须进行预判。 预判: 简单、稳定、独立、高效

如何对业务逻辑进行抽象呢? 答案是,用面向服务(SOA)的思想来设计业务逻辑的动态模型。

顺便插一句,企业应用应该尽可能地向标准靠拢。 其实,每一个标准都是领域专家的宝贵经验。在质疑某一个标准不能解决你的实际问题之前,要非常认真地问自己一个问题,你真的理解标准了吗?通常情况下,为了所谓的“实际问题”而放弃标准,大多是使用者自身的问题,而不是标准的问题。另外,采用标准可以最大程度地简化问题,从而为软件开发组织带来巨大的利益。

9.4 版本依赖

一种好的做法是,把版本依赖看作是软件开发的一部分。在软件开发过程中,我们不再使用第三方组件,而是使用带有版本号的第三方组件。 这种思想上的细微变化,对软件开发和维护具有重要的意义。基于这种思想,组件之间的依赖关系将不是来自总结,而是来自规划,也就是说,版本依赖将成为软件设计的一个重要组成。

9.5 妥协方案

如果真的决定重构,那么应该在故事讲清楚后再开始重构。 有一个办法(准确地说,有一种工作的方式),可以帮助你加快对现有软件系统的理解速度,那就是讲故事。

10 关于组织发展的思考

很多人提及组织发展这个话题时,常常会忽略最核心的内容——知识积累。

不知道从什么时候起,她的身上散发出一种威严的气息,这使她根本无法融入她曾经全心投入过的生活。 她已经很少再想孔如之了。一年前的疯狂早就把思念都扯碎了。那是怎样的疯狂啊,每时每刻都在搜索着邮箱,每时每刻都在拖拽着MSN窗口,这个疯狂的女孩子甚至想到在邮件列表中追踪爱人的足迹。可是,孔如之走了,走得无声无息,走得干干净净。她终于懂了宗方说的技术“疯子”,也懂了孔如之说的“简单”。孔如之真的是简单得毫无顾忌,甚至没有想到过遭遇感情“疯子”的报复。

10.2 知识积累

知识积累是一项长期的工作,我们应该做好这方面的心理准备。从实用主义的角度来看,知识的最高表现形式是常识。 我建议企业经营者对此进行诚实地反思——企业到底积累了什么?企业中到底有谁可以说清楚那些所谓的“知识积累”?那些积累的知识经过了实践的验证吗?它们成熟到可以接受同行的挑战吗?如果上面的这几个问题你无法得到简单明了的答案,那怎么可以说你的企业正在积累知识呢? 很显然,没有积累,就没有知识和文化的沉淀,就不可能在思想和科技方面领导行业发展。在对待知识积累的问题上,我们应该着眼基础、兼容并蓄、分类归档、推陈出新。 从1918年起,陈望道先生先后发表了《标点之革新》、《新式标点的用法》、《标点论之二·标点之类别》等论文,推动了新式标点的使用和普及。1922年,他出版了《作文法讲义》。这是通俗地指导青年习作的语文书籍,也是中国系统地讲述作文法的第一部书籍,在社会上产生了很大影响。1934年6月,针对当时社会上出现的“文言复兴”思潮,他和胡愈之、叶圣陶、陈子展等人发动了“大众语运动”,坚决反对重新提倡文言文,同时对当时白话文存在的问题,如跟群众的活语言有所脱离等,也进行了鲜明的批判,提出白话文必须进一步接近活的语言,主张建立真正以群众语言为基础的大众语和大众语文学。社会上由此引发了一场热烈的语文论战。这场论战进一步促进了文学语言的大众化和大众语文学的发展,同时也为拉丁化新文字运动打下了良好的基础。在这次论战中,陈望道发表了《大众语论》、《关于大众语文学的建设》、《怎样做到大众语的“普遍”?》、《建立大众语文学》、《这一次文言和白话的论战》、《文学和大众语》等一系列文章,对大众语和大众语文学的建立提出了许多科学性、建设性的意见。与此同时,他还创办了《太白》半月刊。这是一个实践大众语理论的刊物。它与林语堂所提倡的半文不白的语录体而办的《论语》、《人世间》等刊物相抗衡。《太白》的出版发行,壮大了大众语运动的声势,传播并扩大了大众语运动的影响。从1938年开始,陈望道又积极提倡新文字运动,发起成立了上海语文学会、上海语文教育学会等进步语文团体,并热情支持“上海新文字研究会”这一群众性的文字改革组织,成为上海当时语文运动的一位主要组织者和领导者。

你知道吗?陈先生毕生从事语言学研究,不是因为他正好进入了这个领域(本来主攻法律),而是他反复思考之后主动选择的结果。很多人都忽略了一些历史人物在人生关键时期做出的选择。其实,这些选择过程中的思考,往往可以体现出那些历史人物的核心思想。在我看来,陈望道先生的核心思想是,语文是一切研究(甚至文明)的基础。从事基础语文研究,是对社会的大贡献。

陈望道先生认为,社会的变革和发展需要一个成熟的语言学体系。只有在一个成熟的语言学体系中,才会有标准化的语言文字。只有通过标准化的语言文字,人民大众才可能正确地表达思想。他立志做这个语言学方面的基础工作。从我们前面摘录的文字,可以看到陈先生为此付出的努力。另外,我们还提到过陈望道先生的《修辞学发凡》。复旦大学出版社在这本书的出版说明中评价道:“在修辞学研究上融合中外、贯通古今、创新理论、缔造体系,被学界奉为中国现代修辞学的奠基之作。”

最后,我想总结一下本节的内容。
•知识需要积累;
•对软件开发来说,需要积累数学、逻辑学、计算机科学、心理学、社会学以及各种工具和方法论知识;
•知识积累是一个长期的过程;
•知识积累的最高阶段是常识;
•基础性研究是知识积累的一个重要形式;
•人是知识积累的关键因素;
•对知识的热爱是知识积累的基础。历史总在延伸,文化总在沉淀,知识总在积累。

10.3 行业成熟

很多人认可现实的复杂性,却从不愿意探究复杂的根源。其实,根源很简单,就是你没有积累足够的知识。就软件开发行业来说,我对复杂性的理解是——缺乏相关的知识,复杂性就萌芽了;缺乏相关的知识而又不关注积累,复杂性就产生了。

先进的思想体系

10.4 知识资产

对软件公司来说,知识就是资产。 有价值的知识是具有系统性的。 我们需要一个知识体系。

知识资产的表现形式包括:
•软件行业的标准;
•软件技术的专利;
•软件企业整理的系统化知识结构;
•软件企业积累的专业知识