成为敏捷软件开发人员的三个关键见解
Friday, January 22nd, 2010- 你不必非要做一个超人
- 敏捷性其实只是思维集
- 成为一名博学型的专家
——Scott W ● Ambler
Programming & Life
——Scott W ● Ambler
Flex开发环境
Adobe Flex Builder仍然是使用最为广泛的商业Flex IDE。它构建在开源的Eclipse IDE平台之上。在Flex 4发布后,Flex Builder即将更名为Flash Builder。除此以外,Adobe Flash Catalyst目前还处在beta版,这是一款设计工具,旨在通过集成设计与编程以将Flash设计人员与Flex开发人员联系起来。
除了Adobe的工具外,Flex开发也已经深入到了现有的各种IDE中。
应用框架
开发软件框架的目的在于实现常见的软件开发模式以提高编程生产率及改善质量。InfoQ注意到2008年推出的一些Flex/ActionScript框架对于Flex使用率的提升功不可没。他们是Cairngorm、PureMVC、Model-Glue:Flex、Foundry、Guasax Flex Framework、ARP、Flest Framework、EasyMVC以及Adobe FAST。从那以后涌现出了越来越多的框架,这些框架丰富了Flex开发生态圈:
Flex与AIR开发工具支持
如果没有调试、测试、日志以及文档,软件开发怎能进行下去。在过去几年中,Flex/ActionScript社区创建了大量的开发支持工具。
Flex企业级开发
Adobe在企业应用系统开发上投入了大量的人力物力。大多数企业系统都需要服务端开发和集成,Adobe的开源产品BlazeDS及商业产品Livecycle DS在这其中扮演着重要的角色。此外,Flex/ActionScript社区也开发出了各种服务端集成工具以支持Flex企业级RIA开发。
展望未来,Flex RIA开发的下一领域将是移动平台。一系列事实表明即将发布的Adobe Flash 10.1将能够运行在大量的智能设备上,比如将要发布的Google Nexus One phone将安会安装Flash 10.1。一旦Flash移动技术横空出世,Flex社区将会大举进军移动平台。
InfoQ将会持续关注并报道Flex RIA领域的最新进展。
我们开发Visual Studio 2008的时候,就是我们整个大部门转型,采用敏捷开发的过程。那我来介绍一下当时我们是怎么做的。
第一,我们发现,如果从CLR(Common Language Runtime,公共运行时)、到Framework、到上面的Visual Studio这三层,同时有大改动的时候,这个是最难的。如果说CLR是我们的地基,Framework是我们的钢筋水泥,那Visual Studio就是我们上面盖的这个楼,三个东西一起改的时候,同时要建这个房子就比较困难。我们就采取了Framework有改动,但是它的基本(core)是不能改动的。如果你对我们.NET Framework比较熟悉,就知道2.0版本是最小的,然后3.0是加在它的上面延伸出来的,3.5又延伸。但它的核心的东西并没有太大的改动,我们就采用这么一个模式:我们给用户足够多的新功能和新功效。这样就保证Visual Studio建于它的基础之上,能够有非常稳定的地基。
在Visual Studio 2008中,实质上我们做了很多的工作。最大的功能就是LINQ (Language Integrated Query)功能,对编译器来说是一个非常、非常大的改动。对我们整个编译器结构的要求,和新加的功能,是很有挑战性的。当时最大的编译器当然是Visual Basic跟C#这两个编译器。我们先花了很多时间做了一个非常强大的prototype,并很早就把prototype给我们用户来反馈,帮助我们设计语言的性能,当时VB和C#都有这么一个prototype,而且我们很早让MVP使用。但是这个prototype最后有多少真正做到产品里面?非常少,不到10%。这就是我们从敏捷开发里面(借鉴的):先要以最快的方法明确用户的需求,一开始我们先是做了这个工作。从做prototype过程之中,我们还学到了什么是容易的,什么是难的。因为很多软件产品,可能一开始用来演示的80%的产品是非常快就可以做好的,但是接下来这20%的难点,可能需要你花80%的时间去做。
微软内部有一个优良(传统),我们自己叫“Dog Food”,就是“吃狗粮”(指自己试用自己开发的软件)。我们在做2008的时候,就Dog Food了Team Foundation Server这个产品,每一个团队把他想做的东西,把用户的场景都放在这个大的服务器里面。作为微软的高层,在任何时候都可以把这些信息汇总,虽然不可能知道每一个项目做到多少,但可以从大面上知道哪些用户体验已经实现了,哪些用户体验还在做,从宏观上面,可以比较快(了解)。如果这个团队看上去这部分可能做得还差得比较远,那这个版本的这个功能我们就不做了,这种决策层上面的问题就比较容易解决。从一个50人的开发团队来说,你可以说有一些用户场景,这个版本是支持的,另一些用户场景,可能这个版本来不及做了,放到下一个版本去做,在这种决策的时候,你可以非常清晰地看到本来计划是什么,已经做到什么,而且场景我们都是要求有一个优先顺序的,按最重要的先做,不重要的相对晚做。
在讨论的过程中,很多时候你就会发现,他也许设计的场景太复杂了。我给你举个例子,我们做很多界面上东西,像“drag and drop”,我看到有一个用户场景,用户可以用undo、redo、cut、copy、paste,这个需要花这么多时间吗?后来发现他们设计的是一套非常完善的方案,第一,undo和redo可以是多层的;第二,两个界面之间切换之后还是可以实现的。比方用一个车,场景是我给你一辆自行车就可以了,他可能给我的是一辆非常非常优秀的奔驰,实际上是用不着的,这个资源实际上是比较浪费的,没必要做那么好,因为用户他不认为这个需要做这么好。这时候你要跟你的团队交流,我们不用做一辆奔驰轿车在这里,可能做一个最基本的就够了。反过来说他这场景是不能没有的,一定要有,但是足够好就可以了,那这个足够好的定义就需要管理层跟团队去反复研讨。我们常常说这是一个hard cut,这个东西我也觉得很好,但是从资源上面来说不够了,我们还是放到下一个版本,我把它砍掉之后,我知道我肯定会听到用户反馈的,但是从这个总体的宏观的管理角度来说,我是一定要做这个决策的。
很多时候团队需要共享资源,在微软每天早上一个开发工程师进办公室后需要知道前一天晚上的build出来没有,在什么地方,有没有什么问题。你昨天晚上睡觉的时候,也许中国的测试团队,给你找到了很多的臭虫,又发现了什么问题。晚上集成build后,我们会运行一整套测试,测试里面又出现了什么问题,今天还有哪些本来要做的backlog任务、工程要做,这些东西你现在作为一个工程师,可能要去各个地方通过不同的工具来把它找到。在Visual Studio的Team Foundation Server里面,我们给你做了等于是一个门户,每一个工程师一上班,对所要的东西都一目了然,这是在我们SharePoint Server的基础上面做的。
我以前在做开发经理的时候,盯得最紧的,第一是还有哪些开发任务没有做,另一方面就是每天产生的臭虫。每一个人产生的臭虫,我都非常快地看一遍,这对开发管理人员来说非常重要,不是说我真的想知道这个臭虫应该怎么解决,我会很宏观地看一下,有个大致印象,这个产品里面哪个部分臭虫特别多,然后可能过了一星期发现,为什么我这一部分一个臭虫都没有看见,这可能是因为开发人员特别厉害,也有可能是这个测试人员特别差,或者协调中间忘了,测试人员根本就不知道有这么一个场景。作为管理者,你要有这种宏观概念,而且可以很快地生成一些报表,知道这个到底有没有问题。
如果你的开发团队比较大,几十人开发团队,一个开发人员比较好,做得又快又好,另一个开发人员可能改这个臭虫改得很快,但下个星期他改的臭虫里又生成很多臭虫,这是很常见的问题。虽然他臭虫改得很快,他生成速度也非常快,说明他改的过程中没有考虑周到,那你怎么能够知道这些开发人员到底在做多少事情。在敏捷开发里,你还要知道同样一个任务,给这个人和那个人,两者可能需要的时间是不一样的。怎样定义分配多少时间、监督每个人是否按时完成,你给他规定的时间是否准确。因为你第一个里程碑的时候可能定义不准确,也许这个任务对第一个人来说太简单了,你给他三天,他两天就做完了,那么下一次,有类似的任务,你给他两天就够了。对另外一个工程师,也许他觉得这个任务比较有挑战性,要花的时间相对比较长。这些数据你都要汇总之后,你才能做你下一个里程碑的规划。如果你不去考虑这些问题,你下一个规划做出来一定有很多的错误。敏捷开发另一个很重要的基本原则,你每做一个规划,每做一个迭代,都是一个学习的过程,你什么地方做的对,什么地方做的不对,你把这些经验再放到下一个迭代的规划里面去,这样你每一个里程碑都比上一个做得更好,更贴近你想做的,跟你实际做到的越来越吻合,这才是敏捷开发的精髓之一。这是一个逐步完善的过程,如果没有敏捷开发这个精髓,我跑上来,就把我下面五个里程碑全部给换了,中间要再调整其实是非常困难的。
最后,我们在用Team Foundation Server进行敏捷开发的时候,要时时刻刻记住敏捷最重要的精髓,不要让过程化的东西来妨碍我们的思维,不要把自己放在一个条条框框里面,敏捷一定要一二三四五。敏捷最最重要的是,根据不同的用户场景、需求,可以很灵活地调整实施方案。这个项目上用法成功了,并不等于说这套方法在另外一个项目上完全可以照搬的。你还要分开来考虑不同的因素,可能客户需求不一样,下面工程师的质量、长处各方面会不一样,因而实施方案会有不同。记住敏捷就是用最好的方法帮你来实现你的项目,它最主要的是跟用户有非常多的交流,帮助你的团队能够团结一致地、很快地朝一个非常明确的目标行进,这些才是敏捷的精髓。
还有最近我们在做另外一款产品Review的时候,也是跟我们Steve Ballmer,我们的CEO,跑上来我就要给他做一个演示Demo,我们的CEO就说现在所有演示都不要做,他叫我们最资深的副总裁,“你就到黑板上面去,把你们这个产品要做出来的三个目标先给我写上去,写完以后我们再做演示,看你这演示有没有达到你这三个目标”,这个跟Steve Ballmer做Review常常会碰到这种情况。
而且我在管理人员方面,很多跟我做了很多年的员工,愿意跟我做很多年,所以这也是作为一个领导者应该比较重要的素质。
我觉得是这些是可以学的,但有些可能有的人就会比较容易一些,比较自然一些,有的人可能就是要学的更多一些。
因为微软里面包括很多公司是这样的,有挑战性的工作是非常多的,如果我这个工作做完了,如果我下面培养出一批人才,能够取代于我的话,那还有更加具有挑战性的工作在等着我去做,所以这个思路不是说有这个人会对我造成危险性,而是我如果有一天能够找到一个,或者请到一个比我更强的员工,这是一个非常高兴的事情,非常令人振奋的事情。
实际上在我的职业生涯中也确实有过这样的经历,我那时候在做Visual Basic开发经理的时候怀孕了,我知道会休蛮长的产假,而且一度还动过可能不回来上班的想法,做全职妈妈的这种心思,所以我那时候就把我下面的一个开发主管,一个开发主管一直培养他,而且当时就是培养他到最后,我去休假之前,说那这个团队就交给你了。等我五个月休完产假回来之后一看,那个团队虽然是我打造的,交给他之后他还是管理的非常好。我说太好了,那你就来做开发经理。那个时候我就去做了我们Division另外一个工作,整个部门的开发总监。
就像我说的,这世界需要能人的事情非常的多,所以你是一个能干的人你不要有这种危险感,因为需要你的地方是非常多的。
作为一个开发主管来说,就是我们叫Development Lead,第一方面,作为管理者,你对这个团队的价值,不仅仅是说你自己写了多少行代码,这相对来说是比较少的,最主要是你这个团队对整个产品的贡献是什么,那还是基于你这个开发的功能有多少,然后你这个功能是不是做得好,你架构是不是做得好,但是你的核心价值是把你这些资源都组合起来,然后能够帮助你团队的员工扫平障碍,让他们非常顺利地开发。
像我最开始做管理的时候,我只管理了三个员工,有一个员工如果做得慢一点,那我最多周末去加一加班,他没有做完帮他补做完就完成了,我觉得相当简单的一件事情。等我那个团队长到10个人的时候,你就发现,第一,不可能我周末再来加班,也不可能把10个人里面有两三个人可能要做的慢一点,如果按同样的比例来说,我不可能把这两三个人要做的东西都做完了。那这个时候你要做,就是我们从这个Skill来说,如果要整个团队都能够非常顺利高效,你就要想“我怎么样让这十个人互相之间能够(协调好)”,就是很多程序是有顺序的问题,把顺序问题安排好,有些东西可能要需要一些决定,尽早的把决定做好,下面的架构可以做好,跟其他团队的关系要搞好,因为他们可能有些东西要拿来,他们先做完之后我们才能做,所以有很多东西Dependency Management,这些东西全部都要管理好,就像造房子,管理一个项目一样。这样管理好你这十个人才能都是马不停蹄、非常高效地把这个东西做好。
等你做开发经理的时候,开发经理因为不是一个第一线的管理者,而是第二线的管理者,这个时候最最有挑战性可能是,你很多东西要通过你第一线的开发主管传达到下面去,如果你开发主管对你说的话不认可,那你的观念、决定不一定真正能够传达到最下面的开发人员。而且你下面的开发主管可能每个人都还要管一摊不同的东西,你怎么样让他们之间能够互相配合、互相合作,从一个大局上面来看你整个这个开发团队缺什么,有的时候他们开发主管在那里面做,他不一定会知道说,我实际上比较缺一个真正能帮我把这个架构搞在一起的人,或者一个特别懂客户的人,那要把这个全部都想清楚,真正打造一个非常强的团队,这又是另外一套的艺术,我觉得。
在微软如果你不懂这产品(技术),你是没有办法做一个合格管理者的,你不仅要做人员的管理者,你还要做这个产品的定义,而且还要跟你的团队交流,什么地方是应该做的,什么地方是不应该做的。
那这三种不同产品很多时候会有不同的进度表,发布时间会不一样。怎么样把里面相同的东西能够整合出来,让大家最有效地利用,而且还要针对每一个产品有他特别的开发。怎么样管理这一套产品线,而且跟我们的市场部,跟我们的营销部,跟我们的DPE(开发工具及平台事业部),那些合作都是在这个层面上面是完全不同的。而且在这上面你就更要想说,这几个产品,就像我们叫Portfolio(投资组合),就好像如果你要是投资,你可能有些放风险基金,有些放银行存款,有些是放外汇,你还要再从比较高的角度上,看你每一个产品到底里面放多少的资源进去,为什么这个产品放这么多资源,而且要看你成功的定义是什么。
而做一个产品的开发经理,这么多资源实际上已经分配给你的,你在这个资源的基础上面把它做到最大最好,所以这还是不同的概念。
在我进微软的时候还是微软比较新,很多产品还是刚刚第一代,像我那时候做Microsoft Access,现在已经无穷代了。那时候刚刚是第一版,当时发布时非常振奋人心的。如果打一个比喻,就比较像我们80年代刚刚开放的时候,那时候商品比较少,用计算机的人数少,相对来说需求也少。所以那个时候从微软来说,只要发布产品就会有很多的用户来使用。因为我们有很多很基本的需求,而市场上却都没有。那我们发布的产品只要大面上不错的话,就可以非常容易地满足用户的需求。从Word第一版开始发行的时候,前面几版你可以想有很多很多基本的功能是,现在觉得都是肯定是应该有的,但是当时都是很新的东西。
但是产品在做了时间久了之后,等你发布第五版、第六版、第七版、第八版的时候,这时有很多基本的用户需求已经满足了,在那个前提上怎么样把你的产品更上一层楼,这实际上就变成一个相对来说比较困难的问题。很多时候,像我们的Office团队最大竞争者不是别人,是前面一个版本的Office。所以在一开始我觉得我们在微软里边定义产品的时候,比方说90年代初,跟客户沟通之后我们就是用一个Waterfall(瀑布式开发模式)这种Model,因为我们觉得我们知道这个产品应该做什么,我们就把它做完了,然后放在外面市场上,相对来说一定是卖得不错的,卖得很好的,所以这是我们比较成功的一个模式。
大概是2000年之后,我们就发现对用户反馈的需求变得非常多,而且一个版本一开始跟用户反馈一次是远远不够的。从开发模式来说,开始时我知道什么是对的,我知道用户需要什么,我只要开发什么,这是我们本来的模式。在那之后,我们的模式时我不太确定用户确实需要的是什么,我们可能要先做一些prototype,试验品出来,让用户去体验一下,体验完了以后再给我们反馈,这是不是他们确实要的,我们在这个反馈基础上再更改。所以你可以看出来整个流程,一开始的想法跟后来想法是不太一样的,而且我们在2000年以后,在后面的开发中,对用户的反馈的需求比以前是大大增加了,而且我们fundamental mindset(最基本的理念),从一开始我绝对知道什么样是一个对的产品,到我不太确定,那我需要跟用户多次反馈,才能知道真正什么是对的产品,那这两个其实是非常不一样的开发模式。我们之后开始用这种开发模式之后,因为微软作为一个很大的团队,确实也碰到很多的挑战,因为很多时候你要想改一点东西实际上是非常难的。
那作为一个大的开发团队,你怎么样能够同时满足客户的需求,又能够在你的架构基础上能够做这种改动。因为最后你的产品还是要满足客户需求,才能够有卖点。你怎么样做这么一个调整,这也是我们在前七、八年中慢慢转型的过程。那相反过来,你如果看,拿我们Visual Studio作为一个例子,从08年,我们前面几个例子看到我们开始大量的出我们叫CTP(Community Technology Preview,社区技术预览版),而且跟我们的客户、开发人员的交流变得非常的透明,很多时候我们很早就把我们想做什么,愿意做什么,有的时候把我们写的Spec,就是产品定义放在网上,给我们的MVP(微软最有价值专家)先让他们反馈,我们现在做很多这样的工作,在这之前都是没有的。
开发的管理方法也是非常类似的,根据不同的项目你要选择对你来说比较合适的方法。如果是一个比较小的项目,你用一个heavy weight(重量级)的方法那就是不合适的。这是为什么微软不会从上面说你一定要用什么样的方法,他考核得是你最后那刻做出来的结果,你的结果是怎么样,能不能在你所承诺的时间里面把东西做出来,你做出来东西用户是不是认可,你做出来的东西后面是不是有很多质量问题,还是说很好用。你在做下面一个版本的时候,就可以反映出你前面做的架构好不好。如果你前面做架构延伸性非常差,你第二个版本相对来说就会多花时间,因为要把前面重新(改造)。
你每换一个开发工具,或者是每换一个开发流程,尤其是团队大了,相对来说实际上是一个比较难的事情。因为你对整个开发、测试,还有工程师,你都要进行一个训练的过程。所以一般来说,我并不鼓励有什么是最热门的,我们都来试一下,因为这个是不太可能达到效果的。很多时候如果一个新的办法在推行之中,大家对这个方法不熟悉,很多时候员工也会有抵触情绪。因为我本来这个用的很好,我也知道怎么用,它里面好的、坏的我都知道了。那现在你如果是一个新的东西,我对它第一不知道,第二没有感觉,然后第三现在我就是不知道怎么跟大家合作,那一开始可能会有生产效率的这种降低。所以从这种方面来说你都要考虑进去,尤其是团队大的话,有的时候是在现有方法之上,说哪些是一定要改动的,哪些是不能改动的,那很重要一方面就是把这个理念,你为什么要改,你不是教你这个团队方法,你要把你想最关键解决的这个问题,为什么你要做这个改动,你现有方法你觉得最最不好的问题是什么,你要把这个问题跟团队讲清楚。那团队在理解了这个东西而且他也认可的情况下,比方说我们以前的开发方法是假设我们知道用户需要什么的,我们现在开发方法是假设我们并不完全知道用户需要什么的。这是一个非常基本的理念不同,你把这个要跟团队讲清楚,那他真正能够明白体会了这个问题之后,那再接下来他会和你一起改进他的工作方法。
工作方法不是我来改进的,是我的团队来改进的。因为他在日常工作(开发、测试)中发现了问题,发现什么是更好的解决方案,他要有这种主观能动性,他要明白我想解决的问题是什么,他才能够主动帮我来想更好的解决方法。那想出解决方法之后,我们大家再分享,一般都是这样。
第一,就是真正的要有这种自信心,要去培养你的接班人。而且是不仅是你要培养你的接班人,每一个重要的职位下面都要有一个接班人,而且这个需要和你重要职位的人一起在培养,因为这是打造一个长久的成功的团队非常重要的一点。因为你没有这种传帮带的话,那你这个团队也许是现在可以把这个产品做出来,如果你们有重要人员离职之后,你还能不能是一个成功的团队,这是一个非常重要一点。
第二点,你怎么样能够调动员工最大的积极性,而且我觉得有的时候中国的员工不够主动,你让他做他会做得非常好,但是你不跟他说的事情,他也许就不做。这个我看得比较多,不管在美国和中国的华人员工里面都是比较常见的一个问题。作为一个管理者,你怎么样能够让他能够非常主动把问题告诉你,而且把解决方案也告诉你,这个是从微软文化上面来说是非常重要的一件事情。
第三个方面,从微软来说是人脑加电脑,从我们做IT来说是人脑加电脑,那实际上最主要的还是人脑,那你是不是真的培养员工,真正是让员工在你团队里的重要性充分的发挥了出来,只有在这个时候员工才认可你的管理的方式,才能认可他是这个团队的一员,才能想到怎么样在这个团队里面发挥最大的重要的作用,那这也是我觉得开发管理者应该多思考的问题,和多做的事情。
但是,我觉得有一些可能文化上面的东西,可能会限制这些员工的发展。我看到比较多的是,有的时候员工他们碰到一个问题,我觉得可能是考试考太多了,他们看到一个问题,他们不太会去跟旁边的人,一起跟周围的团队里面的人,或者跟美国团队人一起交流,一起想最好的解决方案,能够把大家不同的观点整合起来。很多的时候看到他们自己在非常辛苦地在干。那苦干之后真的是做出来成果就说,你有没有考虑到一二三四五六,那你有没有跟这个人这个人去谈过,好像这方面做得相对来说比较差一点。因为我觉得我们考试的模式就说你不能问别人,你都要自己解决。
我们在工作中都是,你不可能一个人把方方面面都考虑全,这是不可能的。所以你一定要跟你团队里面的人搞好关系,一定要把团队里面帮你一起想这个问题,还有什么其他的观点,而且能够非常坦然的把这个观点结合到你的解决方案中去,那我觉得这方面相对来说就是相对弱一点。而且就是这种主动性比较差,如果你没有跟他说要做什么事情,你交代的我都做好了就完了。那这两方面我觉得中国员工需要想一想怎么样加强的地方。
本文将根据我从几个项目中总结的经验,介绍一些成功进行系统级重用的小提示。这些提示并非尽善尽美,我只是想让开发人员和团队领导能对各种策略(技术和非技术的)有所理解,从而成功地进行系统级重用。
业务资产能让你的应用或产品线独树一帜,让你的组织与众不同,最终让你从竞争对手中脱颖而出。开发、发布、迭代改进领域相关软件资产的速度越快,你就越能迅速地满足不断变化的业务需求、让客户满意。如果你只关注于构建可重用的业务资产,那这不仅对业务交付有好处,同时还能在未来的项目中进行重用。
开发人员往往满怀热情地编写技术方案,专注于可重用组件和服务的构建,而解决的问题却在公司内部或开源社区有解决方案。既然你非要这么做,那你就必须尽量避免为已有的解决方案编写新的代码。这不正是软件重用吗?
无论你是给方法、类、组件、库命名,还是给服务命名,要想取个好名字,首先得想清楚软件的目的和功能。合适的名字可以帮助我们找到已有的可重用软件资产。另外,在重构已有软件资产、使其更容易被重用时,这一点也卓有成效。
当你发现doEverything()这样的方法或类似于SendDataToXYZSystemService的服务时,花点儿时间给它们重新命名。评 估应用的现有功能时,不好的名字常常会花费你更多的时间。如果名字太过愚蠢,你可能就识别不出已有的功能,而去创建一个重复的。
除了继续遵守一般的准则外,好名字还应该与问题领域联系在一起——基于业务功能给软件资产命名是个不错的主意。如果你要将更新的订单内容发布到另一个系统 去,那为什么不用PublishOrderUpdates替代SendDataToABCSystem这个名字呢?资产名称全都简单、清晰、准确时,你会 惊奇地发现这很有利于你重用这些资产。
领域中真正有趣的问题是需要经过深思熟虑的,需要与项目利益相关者协作,还需要多次迭代和最终用户的反馈。这一要求对充分进行系统级重用来说是非常宝贵的。如果仅仅因为看起来可重用,那它实际上也许并不可重用……至少目前还不是。考虑一下这些问题:
当你对潜在可重用资产的疑问多于答案时,不要急着概括、增加抽象层次或产品差异性。相反,着眼于那些只针对当前迭代或发布的业务需求和实现。正是因为你可能不清楚未知的内容,所以将想法或功能标记为可重用备选项,但不一定非要使其可重用。
在《软件架构师应该知道的97件事》中,Kevlin Henney在其中一条里提到了“通用之前先简单,重用之前先可用”这个概念。请记住,在项目的整个生命周期中,结合真实用户的反馈进一步理解领域只会对你有所帮助,而不会影响你的目标。
当你认识到需要可重用的软件资产时,规划实现战略就很重要了。如果你用大爆炸的方式处理资产实现,那你创建的软件资产最终会脱离项目当前的需求;由于要增加设计、开发和测试的时间,显然还会拖延进度。无论哪种方式,你都要花费大量宝贵的资源。
相反,可以通过多次迭代来演进可重用的资产,从而减轻这些风险。举一个可重用资产的例子——给用户发通知。我们将该资产命名为Business Notifier。我们提出一个简单的计划——通过数次迭代来逐步实现该资产的一百个附属功能,而不是一下子就创建出来。
迭代1:用电子邮件通知用户预定的业务事件
迭代2:允许用户选择,只接收某些业务事件的通知
迭代3:让用户自定义业务规则,继而生成业务事件
迭代4:通过Web控制台或即时消息应用发送通知
迭代5:能让用户邀请朋友一起接收通知
迭代6:将通知和工作流结合起来,让支持人员进行审查
这显然只是个范例,在特定迭代中加入的功能往往要基于业务需求、优先级、实现的难易程度和其它因素。比如不再优先处理资产时,你可以减少投资,反之亦然。 不论构建为可重用资产的内容是什么,都要在多个迭代中规划其发展演进。这样,你就可以减少风险,保持对业务需求的灵活性,还能只创建那些你愿意投资的资 产。
跨应用创建可重用的软件组件和服务时,力争保持一致性要比符合标准更为重要。如果大量应用程序都使用了特定的可重用组件,那你就可以跟往常一样,将现有接 口作为适配器,让它在后台调用行业标准的API。不过要注意,我并不是建议你盲目地为那些已经有成熟标准的内容创建新代码。
这与要重用的水平业务能力相关。比如说,你在多个应用程序中都需要处理信用卡付款的功能,而在此时又没有行业标准。创建应用可利用的支付API就很重要, 而不是等待标准奇迹般地出现。第二天,如果出现了一个标准,你可以修改现有的实现,这不会对你当前的应用有任何影响。好吧,也许我说得太过轻松了——你可 能需要细微的代码修改和回归测试。但最起码你的处境会比较好,不用修改代码库中的代码。
代码审查能最有效地保证可重用资产被 正确使用。大多数时候,为了赶紧发布产品,开发人员提交代码时并不了解其它地方已经实现了的功能。由于审查代码要花费时间、遵循规则,所以在小规模内这样 做的确是个好主意。关键之所在与其说是代码质量,还不如说是一致性。你可能期望能有一个快速的方法指出哪些资产可重用,将其与代码中的变化相结合。我在代 码审查时经常会找出新的可重用资产。随着时间的推移,你会看到多个代码片段和应用功能中存在的模式和重复的代码,这对起到增效作用很有帮助。
当你看到重构或创建可重用资产的机会时,不要把这些工作跟应用代码的剩余部分掺杂在一起。将它们从源码和版本控制中分离出来,作为一个独立的实体。和其它 内容一样,这也需要迭代地来完成,也不必在产品的最初版本中就有。随着资产演进、变得可重用,可以重构、把它们放到它们自己的仓库中,以便更好地管理。主 要问题是在它们可重用时把它们移出来。在主干代码之外对它们进行版本化和演进,以便更容易地在新项目中集成。
如果你要在可重用软件资产上押宝,把它推广到全世界,那你必须要有一套回归测试套件。为什么呢?没有回归测试,现有和潜在的消费者对资产就没有足够的信 心。重用的基础就是不用再次实现已有的内容,从而获得更好的质量——较少的错误、Bug、不对的需求实现。为了确保能兑现这一承诺,你必须得有完整的自动 化回归测试套件。这不仅有利于当前的消费者,对以后的任何消费者也是有用的。
你可以创建可重用的脚本,完成编译、执行、单元测试和回归测试的报告。无论你构建的是组件还是服务,甚至是业务流程,这都是适用的。下一步合乎逻辑的事情就是把这些脚本集成到持续集成套件中去。
大家总想说服开发人员或开发经理能同意重用软件资产。但如果你还没理解业务需求就一再地去劝说,成功的可能性并不大。不要试图去说服,而是倾听、体 会、真正理解需求。弄清楚业务需求,然后确定能被利用或开发的资产。为什么要这么做呢?因为当你真正去听的时候,你可能会发现现有的资产能完全满足需求,或者根本不能满足需求。也许可重用的服务还需要满足某个性能指标。或者利用现有的服务会增加进度风险。诸如此类。
关键是现有的资产要适用于眼前的问题。倾听,评估,如果合适就说服——一定要遵循这个顺序。
提倡系统级重用失败的原因各种各样,其中包括技术和组织方面的原因。 开发团队是可重用资产的潜在用户,如果没有来自开发团队的支持,你的计划就不可能取得成功。我经常听到开发人员对开发经理说,不想重用,也不想开发可重用 的功能,因为他们觉得实现可重用资产与他们无关。如何解决这个问题呢?不要试图去说服他们,而是和他们共同创建可重用的资产。
如果有个需求是通过电子邮件发送通知,那就和原来的开发团队合作,让他们参与设计。更好的办法是让他们开发部分或全部的功能。如果他们和你联合创建了该资 产,他们就不会觉得这个资产是强迫他们使用的黑盒子了。他们会在组织里和他们的合作伙伴分享该资产,从而帮助你促进重用——你会对此感到惊讶的。
将可重用资产投入生产环境之前需要做一件事,就是与生产支持人员沟通。让他们投入进来,分享你的设计,及早并经常获取他们的反馈。这不仅能让资产可被支持 (想象一个没有日志、辅助工具、记录关键指标功能的可重用资产),还能让你拥有一个有价值的的合作伙伴。生产支持人员很快就会信任你的资产和服务,并要求 多个项目都利用这个功能。卖出重用资产是一回事,合作伙伴表示支持又是另一回事。
技术实践、协作和务实相结合,可以慢慢扩充你的可重用资产库。本文介绍的这些小提示都是我在日常工作中为了提高成功率而反复使用的。我非常想听听你在促进有效软件重用时总结出的经验,无论它们是否有效。