软件工程
软件开发的管理
[编辑]最近读了关于微软的软件开发模式的资料,又读了关于“极端编程”的资料。了解了现代企业的现代管理模式。“极端编程”是指软件开发的极端状态,也就是理想状态。微软的方法更具体,“极端编程”在开发过程中各方面人员的相互交流方面更成熟。总体上两种方法在大的方面都是雷同的。
关于微软的开发模式的资料可以参考《微软的秘密》,关于极端编程的资料可以参考 http://c2.com 。
综合两者,简述一下软件开发的方法。
保证开发计划按时完成和产品质量的方法:
开发要完成的内容是根据用户的需要确定的。在微软是由销售人员确定用户需求。这里主要说明“极端编程”的方法。在极端编程中,用户确定要开发的功能,用户可以把对自己更重要的功能放到前面先完成。开发人员对这些功能提出每个功能实现的时间,用户如果认为时间太长可以取消一些功能。这样,通过这种协商和反馈,保证了开发的最大价值。同时,因为是开发人员确定功能实现的时间,因此,计划必要容易按时完成。特性不要要求太具体,要简单勾勒。
实际上,用户开始不知道自己需要什么,这需要开发人员研究用户行为,提出可以实现的效果,用户对效果进行评价和修改,来确定开发的目标。当开发完成时也要提供给用户进行试用,获得反馈意见,对产品进行改良。这也是和用户不断交流的过程。这种交流保证了产品确实是用户需要的。
对于每项功能,由开发的组织者和开发员讨论制定详细的完成步骤,确定每一部分要达到的具体效果,写详细的文档,描述每个界面完成的外观和函数的功能。这叫任务引擎。任务引擎不是一次写成的,可以随时间不断详细化。
根据任务引擎再编制详细的时间计划,将任务引擎划分为若干个任务,每个任务由一个人负责,这个时间计划要由每个具体的开发人员提出或协商每个任务和每个任务的具体部分的完成时间,这个时间计划要细分到半天至三天,至少一个星期。在每项任务的完成时间后面要留有缓冲时间以应付意外情况和时间估计的不准确。只有计划的时间单位的细化才能保证任务的完成在完全的掌握中。
在时间计划中有界面冻结时间、文档冻结时间、代码冻结时间,这样保证了计划的相互关联的部分不会影响计划的完成。
开发部门和测试部门是相互独立的部门,几乎每个开发人员对应一个测试人员,两者的人数是1:1。要求开发人员每天把完成的代码放到服务器上,每天测试人员进行昨天完成的代码的测试以及以前代码的测试,并将发现的问题发到服务器上,反馈给开发人员。有时因为发现的问题太多,管理人员会发现开发的难度,因此会取消部分任务和开发。测试人员和开发人员要完成的工作都有详细的规范,规定具体要完成的内容。通过专业的测试,保证了软件的质量。
在开发中,管理人员要追踪计划的完成情况,及时发现问题,指导问题的解决,保证计划完成,根据问题调整计划。
微软把每个软件版本的开发过程分为几个里程碑,大概每两三个月一个里程碑,每个里程碑实现部分的特性(软件功能。在微软,软件功能被成为特性。)。最重要最基础的特性放到前面的里程碑中,不重要的特性放到后面的里程碑中,这样,如果要保证软件的按时发布,最后可以删掉一些不重要的特性保证软件的按时发布。每个里程碑都要在公司内部和外部进行软件的发布和各种公共测试,保证了用户的反馈和这部分功能的最后稳定。这样,避免了到软件发布的最后时期才进行各种公共测试的被动。也加大了和用户交互的机会。
在每个里程碑中,一般都留下三分之一的缓冲时间,来应付各种开发的意外情况,使开发工作可以从容完成,如果到了缓冲时期,为了保证计划的完成有可能取消一些不必要的功能。缓冲时间在“极端编程”中称为“时间因子”。
这些方法实现比较复杂,但这是已经有大量工程和公司的实践。不是理想的空中楼阁。针对具体公司,根据自己的管理条件,可以分批逐步实现。或者没有能力实现,也可以参考先进的项目管理方法,认识到自己管理上的各种问题产生的原因,有一个管理的目标。
参照软件的项目管理,建筑的项目管理是相同的
[编辑]建筑项目采用设计与施工分离的方式,从而强化了设计与需求分析的过程。
现在通过效果图的方式,加强了和用户的交流。
初设和司令图就相当于任务引擎。相对于任务引擎的细化,在基础设计阶段要完全做好相互间的资料配合,所有协调工作首先完成。
现在以卷册为计划单位,太粗,常常不能保证计划完成。应该计划细分到概念设计、计算书、提资、图纸。在每个阶段同时校核。从设计初期,就一对一校核。能及时发现问题,及时解决。同时要加强追踪力度。
里程碑使整个工程的完成有一个清晰的思路。
各种互提资料的冻结时间,可以保证配合顺利。
先进的人事管理的几个要点
[编辑]每个人管理的人员适当的人数是8个。这样才不会导致交流瓶颈。
扁平式管理:就是打破上下级关系,不只是垂直交流,而是大力推进越级交流和平级之间的相互交流协作。增强水平联系,减少垂直联系。尽量减少办事的环节。
不强调等级,管理人员也是普通人员,不以职位的高低评价,以业绩来评价。职员的业绩如果好,甚至可以超过经理。
采取多线晋升制,管理线、技术线等平行发展,使人根据自己的条件选择发展方向。
职位升降、奖励多少、淘汰率都根据业绩评价来决定,有专门的小组进行业绩评价。并且业绩评价不是按年,而是至少按月。这样才能随时保持员工的压力和动力。
建立强有力的中层管理层来保证各种企业功能的顺利完成。
对企业有完善的监督机制,保证经营方向决策的科学性。
极限编程(eXtreme Programming,XP)的特点
[编辑]XP在很多方面都和我们传统意义上的软件工程不同,同时,它也和传统的管理和项目计划的方法不同。这些方法在软件工程和其他管理活动中都有借鉴意义。
特点如下:
不采用瀑布式的软件工程方法,而采用原型法。将一个软件开发项目分为多个迭代周期,每个周期实现部分软件功能。在每个周期都进行提出需求、设计软件架构、编码、测试、发布的软件开发的全过程。每个周期都进行充分的测试和集成。这样的好处是可以不断的从客户方面得到反馈,更逼近实际的软件需求。通过频繁的重新编码的过程,可以非常适应功能更改的需求,同时增加软件的易维护性。在不断的迭代中,避免架构设计的重大失误造成的软件不能如期交工,避免了软件设计的风险。
在软件设计中,强调简单性,就是坚决不做用不到的通用功能。同时,也不刻意避免重新编码,只有不断的重新编码才能保证软件的合理性。不害怕对整个软件推倒重做。认为重新编码是很正常的现象。每次的重新编码都会大大减少软件中的熵值。
在专业分工中,提出在开发团队中要有全职的客户人员的参与,同时在软件团队中也要有自己的领域专家。这样,可以和客户充分交流,彻底了解应用需求。这种软件需求的提出不是一次性的,而是不断的交流。
也有专门的软件架构的设计师,首先进行软件整体架构的设计。这种设计一般使用UML语言。
在软件开发的顺序上,和传统方法完全相反。传统方法是按照整体设计、编写代码、进行测试、交付客户的方法。而XP是按照交付客户、测试、编码、设计的顺序来开发。首先将要交付客户的软件的界面作出来,先让客户对软件有实际体验,这样,可以获得客户的更多的反馈,使需求可以在开发前确定。在编码前就先把测试程序做好,这样,编码完成后就可以马上进行测试。通过不断的测试来保证软件的质量。在进行软件架构设计之前就进行编码,可以使问题更早暴露,可以使最后的软件设计更体现编码的特点,更符合实际,更容易实现,也保证了设计的合理,保证了软件设计的大量决定的正确性。
在项目计划的实现上,每次的计划都是技术人员对客户提出时间表,由最后的开发人员对项目经理提出编码的时间表。这种计划都是从下而上的,不是从上到下的,更容易保证计划的按时完成。同时,多个迭代周期也使工期的估计越来越精确。
在分工上,强调角色轮换,项目的集体负责,分工的自愿性。分工的自愿性就是每个人的工作内容不是由项目经理分派,而是由每个人自愿领取,这样保证了每个人可以发挥自己的特长,适应自己的情况。当然,在每个问题上都要有唯一的决策人,同时,也要经过充分的交流和沟通。角色轮换就是在项目中,一个人在不同的周期中担任不同的角色,可以保证每个人对项目的整体把握,方便项目中的沟通和理解。项目的集体负责,就是每个人不是完成自己的工作就可以了,要对整个项目的完成负责,任何人都可以对工作的任何部分提出自己的建议。任何人都可以从事任何工作。任何人都要对整个项目熟悉。这样做的优点是可以充分的锻炼人、可以发挥每个人的积极性、可以使项目不依赖于某个特定的人,方便今后的软件的维护,通过工作内容的变换可以提高人工作的兴趣。通过角色轮换还可以使每个人都劳逸结合,方便相互理解,避免由于不理解而造成的各种配合问题。
保证8小时工作制,避免加班。
(我加几条:要有充分的培训、要有每个人的提升空间、制定报酬要根据对企业的贡献大小,而不是职位的高低,允许下属比上级薪酬更高,薪酬的高低取决于绩效评定,同时绩效评定要尽可能量化。并且推行淘汰制。同时有有效的招聘制度。有强有力的后勤保障制度和轻松的企业文化。)
提出了成对编程的思路,就是每个模块的编码都是两个人一起干,共用一台电脑。这样,一个人编码时,令一个人就可以检查代码,或对编码的思路进行思考,写文档等。不再有另外的测试人员,两个人同时完成代码的测试,并且使先写测试程序然后再编程。这样避免了编程人员和测试人员的矛盾。也解决了一个人自己检查的局限性。两个人共同检查可以避免大多数的错误。在共同编程中还可以进行经验的交流和传授。也避免了将一个工作一直干下去的无聊,交流增加了情趣。并且两个人共同工作也增加了工作量的弹性,使项目计划的瓶颈工作能尽快解决。根据成对编程的思路,开发小组也可以分为两个小组,一个小组进行开发,另一个小组作改进和bug修正等工作。也有同样的效果。
在人员的分工上要灵活,要保证软件开发中的角色的齐全,但每个角色可以由几个人共同担任,也可以一个人担任几个角色,并且在项目的不同时期,不同角色的人员数量会不断变化。
每天或隔天,开一个站立会议(保证开会时间尽量短),来解决工作时间不一致和相互打扰工作的情况。在每个迭代周期也有一个计划和分工等的全体大会。
XP的实施方法就要求能适应工作中出现的问题,不断对XP进行改进,而不能照搬套用。
XP的目标就是发挥人的最大积极性,保证充分的交流。
XP的优势是能很好的适应需求的更改、设计框架的更改。
XP采用和建立一个通常框架相反的方法来适应需求,而是尽量简单。
软件开发的流程
[编辑]对开源软件来说, 首先是软件功能的讨论。 相互竞争的软件的评价。 能否利用已有代码。 软件架构的讨论,使用UML 开发人员的落实 开发中的相互交流
开源软件项目的几个问题
[编辑]启动一个项目首先这个项目要满足发起人的需求。就是要为了使用而开发,而不是为了开发而开发。只有项目能满足自己的需求,这个项目才能坚持下去。如果开发是为了别人,这个项目的前景不妙。
开发的项目要有鲜明的特点,明确的诉求点。如果是和其他已有软件功能相近,就加入其他项目,或建立一个已有项目的分支比较好。
不能只是因为语言的关系,就新建一个开发项目。重新学习一个新的语言花费的时间比新开发一个软件要少的多。除非特别需要,做一个软件的另一个编程语言的版本更好。尽量保证兼容。
一个项目最好做成国际版本。这样,不但中国人能加入开发,外国人也能接手。这样,项目的存活的可能就会高的多。
实际上,现在中国的开源项目,做一个国外项目的中文版本是最有效的,不但是翻译,更重要的是解决所有的不兼容中文的问题。当然,还要保证双向兼容。从双向兼容的角度来说“中蟒”不是个好项目。
很多开源开发人员感觉既然是业余搞,就想怎么干就怎么干。实际上,开源项目更应该讲究效率,更应该讲究效果。(效果和效率是不同的)。开源项目相对商业项目来说,人力更少,更应该考虑投入产出,考虑成本。所以,按照我上面说的几点,会使开源的力量能得到更好的发挥。
一些商业软件在开发过程中大量使用开源软件的内容,但没有遵循开源协议,实际上也是一种侵权行为。
聊聊软件架构、编程语言、软件、开发平台
[编辑]层次和组件
[编辑]软件架构的一个重要概念是层次,通常软件通过分层来达到灵活的发展。比如操作系统和其它软件的分离,比如中间件的概念,比如网络的7个层次。目前一个比较重要的层次概念就是表现、逻辑、数据的分离。
另一个重要概念是组件,组件并不是在vb语言发明后才出现的,unix的各个小程序通过管道、shell语言相互结合,实际就是组件的表现,编程语言的库也符合组件的概念,com其实就是vb的特殊的库。zope的product也是组件的一个典型。还有netscape插件、winamp插件等都是组件的概念。组件就是在一个平台上有很多相互独立部分,这些独立的部分可以分别安装,最后通过胶水语言来调动各个组件共同完成任务。操作系统和其上面的各个应用程序就是组件模型的体现。目前尤其以com和java bean为典型。
程序规模的大小和编程语言
[编辑]程序越大,划分的层次和组件就越多。但如果是小程序,应该从不分层次和组件开始。从小程序到大程序的发展过程,就是不断的分层、分组件的过程。不同的编程语言对应的程序的规模不同。但因为不可能总是大程序,也不可能总是小程序,能适应各种不同规模的编程语言最好,以免要学习很多语言,并在很多语言之间转换。比较能适应不同规模的语言是python,即照顾了函数型的小型程序,也照顾了面向对象的大型程序。perl、php是小型语言,java是大型语言。但对程序规模适应能力最强的是scheme,它编写的最基本的语言甚至不用输入输出,也可以没有数据和程序的区分,而最后scheme还有专门的对象、类、组件这些能适应大型程序的语言特征。但是不是scheme做的不够专业,我就不知道了,至少可能速度慢。
利用现成的库还是自己实现库功能
[编辑]我认为首先尽量自己实现所有的功能,只有必要的时候,或更进一步发展的时候才用他人的库来实现自己需要的功能。因为自己实现的东西才最随心所欲,可定制性更强,也不受他人库的局限,独立性也强。在原型设计阶段,不要求稳定性和复杂功能的时候,全部的自己实现会尽可能简单,而不受库的限制而做很多额外的工作,和基本任务关系较远的工作。
我刚刚完成的一个“文章交换”的程序就是一个较少借用外界功能的原型,用户注册等的功能都是从零开始自己完成的,在这个过程中,没有学习和跟踪cmf的知识也能完成程序。虽然最后有可能在cmf中实现,但独立实现的乐趣很大,感觉很简练,很纯粹。还有一次在acad中用autolisp实现了一个类似unix的info的东西,另一次是在excel中用vba实现了一个文件转换的程序,分别利用了acad和excel的输入输出功能,最后都感觉很罗嗦,感觉还是独立出来最好。
最后结论是,如果能独立就不要利用太多的库,等程序发展了,有必要时在再成熟的库来实现,程序独立后往往很方便。试试脱离java、脱离zope、脱离kde来编程,看感觉如何。
程序的友好性和成熟性
[编辑]最开始很多用户会选择界面很友好的程序,喜欢程序自动帮你把很多事情都搞定。如果进一步深入,就会发现友好的自动的程序常常限制了你的手脚,并且没有你需要的特定的功能,这是你就会寻找更专业的程序,最后更专业的程序常常是界面不友好的文本界面的,经过了十几年发展的老程序。
前面所说的两种程序实际对应着商业程序和开源程序。商业程序常常是友好的,但也是不成熟的,常常动不动就升版,但却不能满足你的需求,因为人们的需求太多了,软件公司只能挑最主要的,另外,软件公司还会不断的紧跟潮流,推出新功能,这样就可以赚到更多的钱,但也同时把熟悉老程序的用户给抛弃了,也同时有很多虽然老,但很好用的功能给抛弃了,一个全新的开始也意味着从头再来,这是bug最多,用户需求的满足也最少,商业公司的最终结局是破产,这是首先感到悲伤的是那些软件的用户,所有的使用经验都全没用了。
而开源软件跟不上潮流,但发展了十几年,有所有用户想到的功能,也没有没完没了的升级,因为它早就稳定了,也没有破产的危险,因为它不需要盈利,另外,开源软件经过了多年发展,内核会越来越小,功能会越来越专一,不同的程序之间会越来越默契,小而精,很纯粹,不会出现“肿件”的情况。这些老的程序常常只能在unix上找到。在这里推荐一个网址:http://learn.tsinghua.edu.cn/homepage/015450/ ,讲的就是怎样抛弃时髦程序,选择老程序的过程。
选择编程平台的层次
[编辑]选择低层次的平台,比如c,容易发布,就是一个可执行程序,功能强大并灵活,但实现任务所需要的劳动很多。
选择高层次的平台,如cmf,有大量的学习任务,但完成所需功能时键入的代码少,另外,如果发布程序就要带着python,zope、cmf。总是拖家带口。
选择什么平台,就看你是要求功能还是要求开发速度。
本来我对组件的理解是和你一样的,都是看到“com”--“组件对象模型”,认为它才是组件。但最近接触了zope和scheme,zope的product也自称组件编程,scheme的unit类也说实现了组件编程。再联想到unix环境的大量小程序的协同工作。在我头脑中,组件的概念就扩大了。
- 首先组件是相对于封闭的程序来说的,封闭的程序完全自己实现功能,而不能由第三方添加功能。如果一个程序提供一个接口,能被第三方添加功能,那么这个程序就实现了一个组件环境。比如编程语言的库,比如winamp的插件,netscape的插件。
- 如果这个程序本身的大量的功能都是在组件环境内实现的,和其它组件处于同样的地位,而组件环境被精简为一个核心平台,那么可以说这个软件是组件架构的。比如操作系统,比如操作系统的微内核结构。比如acad的ads环境,等等底层接口开放的软件都是组件架构的环境。
- 如果组件都很专业,只实现专一的功能,并且有完备的接口,能很容易的组合到一起,并且通常由脚本语言,将各个组件组合在一起来完成最终的工作,那么就可以称作一个比较专业的组件环境,比如java bean,比如zope的product,比如scheme的unit。比如unix的shell环境。com的环境是最容易的,能够以可视化的方式组合到一起。
- 如果组件可以由任何语言编写,可以实现运行时的二进制的调用,并且一般经过了标准化,那么就成为了标准化的组件环境,比如corba和com,比如soap。比如xmlrpc,比如apple的cocoa环境,比如.net。
上面就是我头脑中的组件的概念,只有最后的组件的概念符合你的概念。
设立软件项目的不同方式
[编辑]现在开源软件很热门,在很多人的观念里讲到软件开发就是开源的方式。
下面讨论一下开源的限定条件。
比如开源的开发者都是因为自己有使用的需求和空余时间,并且对开发有兴趣才参与开源项目的。
如果是自己有这方面的能力,并且开发出来的软件对其他人很有用,而自己对相关的软件不是特别有兴趣。在这种情况下启动一个开源项目是不可能的。但可能的方法一是办一个商业软件的公司,使自己的能力能够为他人服务,也更多的发挥自己的特长,将本来做不擅长的工作的时间用来做擅长的工作。另一种方法就是成立基金会或寻求项目资助,寻求项目资助的往往是科研项目。基金会或科研立项的方式能够产生一个大家都可用的成果,也保证了开发者的工作时间。不过基金会和科研立项的方法范围比较窄,不能代替商业开发。
贡献
[编辑]本文章最初作者是:tomz。tomz的网页:http://tomz.126.com