背景介绍
我从大学05年开始直到现在就总共干了10年的软件开发,期间参与了各种类型的软件项目开发,包括高校和企业应用软件项目,外企的金融软件项目以及互联网软件项目,也参与过最近流行的移动端互联网项目的开发。分别在外企、创业企业、自己创业和中大型互联网公司工作过,所以实际参与的互联网项目种类繁多,工作过的公司类型也较多,因此对于软件项目开发这件事情有一些自己的思考和实践经验。
从2011年开始接触到敏捷项目管理,期间学习和实践了像Scrum和看板方法等敏捷方法,也进行了包括持续集成、代码评审等多种敏捷工程实践,也使用了谷歌公司发明的OKR工作方法。因此对于敏捷软件开发也有一些总结的经验。
因此本文就是将自己多年的软件开发和敏捷软件开发的多年学习和实践经验进行汇总,形成本文。
软件的价值
提高数据计算和存储效率
首先软件带来的价值就是提高工作效率。互联网盛行之前软件开发行业主要是为企业开发应用软件,它的价值是提升企业员工的工作效率,比如财务软件及各种管理类软件,主要是解决信息存储和检索问题,解决数据计算效率问题。
提高信息传递效率
其次软件及互联网带来的价值是提高信着互联网技术的广泛应用,软件给人们带来的价值是以更低的成本,更高的效率传递来传递信息。
还有其它的一些价值。上述两类价值是软件及互联网带来的核心价值。
那么我们软件开发的目标就是通过一系列的过程和活动让软件的价值得以体现,脱离了实现价值的软件开发就是耍流氓。
另外我要强调的是价值它绝对不能等同于软件功能,开发软件功能只是第一步,只有用户去使用软件解决了问题,提高了效率之后软件的价值才得以实现,软件的总价值等于所有软件用户获得价值总和。
传统软件开发的问题
由于我在不同类型的软件公司工作过,参与过不同类型的软件项目,因此对于传统软件开发的问题也有比较全面的认识,我总结传统软件开发存在的最为关键的问题有下面这些。
不以交付价值为目标
传统软件开发最大和最根本的问题就是目标经常会不正确,这时导致传统软件开发一系列问题的根源。国内传统的软件开发往往是给大企业或者政府部门研发企业应用类软件为主,而软件公司作为施工的乙方,乙方的商业模式决定了乙方开发的功能越多,功能越复杂则软件的价格越高,因此软件开发者的目标是往往尽可能让软件项目能够获得更高的售价,能够尽可能让甲方的软件研发决策者满意为主,双方的合作是基于合同约定内容进行的。而甲方的决策者往往不是直接使用软件的管理者,管理者自上而下考虑问题的时候经常会考虑得非常全面,专业而复杂,可能会给基层员工带来巨大的软件使用成本,但是往往这些会被决策者忽视,软件在实施的过程中,管理者往往需要付出非常高的管理成本去督促和控制员工软件的使用情况,如果管理者一旦放松控制则会出现员工就不使用软件或者就敷衍管理者的管理。这就是为什么我们经常会听说企业购买的软件有80%是根本不用或者很少使用的,而企业还需要花费巨大的软件、硬件建设成本,另外还有员工的巨大使用成本,另外企业的业务也会经常变化,往往越专业越复杂的软件应对变化的能力越弱,导致企业之前购买的软件因为业务发生变化而无法继续使用。而真正给企业带来的价值却非常少,有点软件根本无法提高员工的工作效率,反而会浪费员工的时间去使用和维护软件,反而给员工带来巨大的累赘。
不以交付价值为目标的软件开发最终给客户交付的是低投入产出比的一堆软硬件产出物,也许短期内某些管理者对于这些能够体现政绩和业绩的表面交付物是满意的,但是长期来看越来越多理性的企业会更加注重价值的交付,而且随着越来越多国企改革,政府部门的改革都会让
糟糕的软件质量
尽管为了保证软件质量,我们有各种各样的软件质量标准用于控制软件流程和产出物,比如大名鼎鼎的CMMI模型,那详尽而严谨的各种标准让我们看起来觉得非常专业;我们还设置了各种岗位来检测软件质量,比如测试和SQA等等,种种这些都“然并卵”。传统软件开发方法开发出来的软件质量非常糟糕。
先说用户能够感知的外部质量的情况,我们开发的软件上线实施有一部分往往是根本不符合企业的实际业务情况,无法解决企业的问题,没法带来价值。有更多的软件是实施后,强制员工使用了一段时间后,员工用起来觉得更麻烦,用户体验机器糟糕,不能带来价值,反而相比原来的工作方式增加了很多额外的成本,时间一长管理者觉得确实没有价值,也就将这个软件丢弃了,这些都是需求层面的质量问题;还有一部分是软件代码的缺陷质量问题,软件工程师都是在被进度充分压榨的情况下编写代码,往往测试时间有限,因此隐含了大量的代码缺陷留着用户一个一个试出来,给软件使用者带来巨大的额外成本。
再说说用户无法感知的软件内部质量的情况,内部质量优先级低,往往在软件企业里也没有什么人关注,没有专人的去检查内部质量,因此代码的质量那是惨不忍睹。糟糕的内部质量其实也会反映在外部质量上,内部一团糟,就很有可能隐含了大量的缺陷,另外软件往往还要根据业务调整而维护,时间一长,由于糟糕的内部质量更是让软件被改得一塌糊涂,而且由于项目人员更替频繁,往往导致软件的代码没人敢打动,以至于软件代码彻底腐化。
为什么我们设置那么多软件质量标准和岗位,软件质量依旧还那么差呢?我觉得最重要的原因是企业定制化软件开发和维护成本极高,另外由于软件开发目标不正确还导致企业软件功能过于庞大更加增加了开发成本,另外在激烈的市场竞争下价格被拉到成本之下,而软件企业往往为了获得订单还需要付出一些灰色成本(你懂的),因此在高额的成本之下,软件企业不可能付出更加高额的成本去执行质量标准。所以我们经常看到的现象是大家开发的时候是在非常紧迫的时间里完成软件开发,中间的质量控制流程是能省就省,如果必须要达到某个标准,最后大家在统一去补充一大堆的文档应付了事儿。
开发者沦为低价值的体力劳动者
传统软件开发者往往是顶着脑力劳动者的帽子干着低价值体力劳动的活,因为虽然企业是定制开发软件,但是绝大多数功能特性都是相同或者相似的,这就导致软件开发者几乎开发每个项目要么是拷贝粘帖,要么每天用着相同的经验和技能将企业的需求简单转化为代码,这种工作对员工来说毫无挑战性,员工的技能也得不到提升,个人的价值得不到实现,员工满意度怎们可能高?久而久之员工自然就容易流失;这也是很多软件企业人才更替频繁的主要原因,尤其是一些专门做软件外部项目和人才外部的软件企业这种现象更加严重。员工的创新能力弱,软件企业就不可能形成自己的核心竞争力。从目前来看很多专门的外包公司已经倒闭或者被迫转型,这也是很重要的一部分原因吧。
现状及未来趋势
就中国软件行业的市场来看,最近几年的互联网企业的蓬勃发展,让软件开发者面临的市场和用户有了巨大的变化。
首先软件的使用者有了巨大的决定权。在自由竞争市场里,软件使用者有自由的选择权,软件价值不高,软件使用成本高,用户不喜欢用,都将成为软件被抛弃的原因,这与企业软件由管理者决定的情况大不相同,传统企业软件是一个相对封闭的垄断市场,软件使用者被迫接受,因为用户没有选择。
其次软件的开发者变成了甲方。软件开发者往往是互联网企业内容的开发者,所以软件开发者不但要交付软件功能,还必须要对软件的价值负责,还需要考虑软件的成本。
再次软件变成了一个长生命周期的产品,软件的可维护性变得更加重要。互联网公司内部的软件往往是需要长期维护的,它需要随着业务的发展持续改进和优化,因此软件的内部质量显得尤为重要。
另外,企业软件市场也必须改变。首先更多的国企私有化,政府也在继续深化改革,企业客户也越来越意识到软件获得价值比软件功能更加重要,另外由于软件行业人才越来越不愿意开发没有技术含量的定制化软件,因此未来企业软件市场也会标准化、产品化和互联网化,目前企业市场兴起的SaaS正是这个趋势的最好的印证。
为什么需要敏捷软件开发
正因为当前传统软件开发已经根不上时代发展的要求,传统软件开发出来的软件无法让客户满意,给客户带来的价值很低,而客户需要花费很高的研发和使用成本,性价比实在是太低,它已经老态龙钟了。而敏捷软件开发的出现正好是解决传统软件开发存在的问题,它更能符合当前市场及客户对于软件开发的需求。因此目前成功的互联网企业都在使用精益和敏捷软件开发方法,连很多传统的软件企业都在谈敏捷转型。那么敏捷软件开发到底解决了什么问题呢?
首先敏捷软件开发纠正了软件开发的目标为交付价值。根据我的理解和经验,敏捷软件开发的核心在于目的是交付价值给软件使用者,它强调可以工作的软件比详尽的文档重要,意思就是可以帮助用户提高工作效率,帮助用户解决问题的可用的软件是软件开发的最重要的目标。它还强调了客户的参与比合同更重要,因此让客户更多的参与可以开发出更加符合客户需求的软件。
其次敏捷软件开发强调一种内建的质量保障体系来全方案保障软件质量。它让软件开发的交付变为更加小而频繁的交付,这样就可以更快地交付给用户使用,让用户尽早对软件给予反馈,保障了软件需求的正确性。它强调构建软件的自动化测试体系,频繁的运行自动化测试,尽早发现问题和解决问题,保障了代码质量,还有结对编程、持续重构和代码审查等检查和反馈等技术活动来保障质量。
最后敏捷软件开发鼓励开发者创新和创造,持续集成、持续交付和自动化运维等很多敏捷工程实践都是一些将开发者从繁琐的重复的工作中解脱出来,鼓励开发者使用或者开发自动化的开发、部署、测试等工具来代替人的工作,另外敏捷开发也对人更加重视,它强调沟通和协作的重要性,开发者在敏捷软件开发项目中往往具有更高的员工满意度。通过我们的实践证明,敏捷项目中的团队成员的协作能力、目标性、积极性和团队凝聚力都远远高于普通项目团队。
敏捷实施经验
怎么组建和建设团队
我认为人和团队是敏捷软件开发中的核心。而往往传统软件开发项目中将人视为普通的资源,认为人是召之即来,挥之即走的资源,这种思想正是把人当作简单的可以随意代理的体力劳动者,在这种指导思想下,组织在人方面会以极低的成本对待,员工对于组织也没有任何忠诚度可言,那么组织需要以极高的成本去管理和控制员工。因此在一个传统软件项目的组织方式、管理方法和企业文化的组织中去实施敏捷是缺乏灵魂的,没有良好的土壤和环境,希望结出不一样的果实,那简直是缘木求鱼。
组建团队的建议是先选择那些价值观和文化更符合的人,它比人的技能更重要,因为技能代表人的过去,而价值观和文化却决定他未来将如何做。应该优先选择符合这样一些特质的人。他的工作目标是为用户创造价值,而不是将个人的专业能力提升作为工作的目标;他是一个坚守质量的人,对于自己专业领域的技艺有着不懈追求的人。他是一个有着较强的协作意识和能力的人,而不是一个强烈的以自我为中心的人;他应该是一个具有持续学习和创新能力的人,他不能容忍自己一直做着枯燥的重复性工作。
要组建一个目标一致的可以独立交付价值的全功能团队。目标不一致是对一个团队伤害最大的,如果一个团队都分属于不同的职能部门,团队中的人都只对自己的职能部门领导负责,那么这就组成了一个一盘散沙的团队,这样的团队效能非常低下,团队成员都会想着如何才能少干点儿,如何体现自己的成绩,如何让自己的老板满意,大家的人也不在一起,心就更不在一起了,这不能称之为团队。我建议敏捷团队应该首先人在一起,而且团队的目标更应该明确,将团队所有人的责权利与团队目标建立起联系,团队成员尽可能在周期内都是全职参与的,团队成员应该包含产品、研发、测试、运营等岗位,最好将业务运营和市场推广人员都纳入进来。
团队要保持小,一般在5-7个人左右,人数过多则会导致沟通成本过高,决策效率低下,协作起来变得更加困难,所以团队人数大大超过7个,则应该考虑按业务的特性进行拆分为多个小团队。但是另外一个问题出现了,团队之间的沟通没问题了,跨团队的沟通往往就变成问题了,尤其是敏捷团队和非敏捷团队之间的沟通更是障碍。一般多个敏捷团队之上应该有一个产品管理委员会,产品管理委员也要形成定期的沟通机制,如果大家都是同一种敏捷文化,跨团队沟通自然也问题不大,关键是敏捷团队和非敏捷团队之间的沟通我也没想好该怎么沟通呢?
将更多的责权利下放到团队及员工。去中心化带来的好处就是每个人都是中心,能够充分调度每个人员的积极性和创造性。去中心不等同于团队成员就可以为所欲为,而更应该制定更加严格和细致的纪律,敏捷团度不是没有制度,而是有更为严明细致的纪律。只不过这些纪律是开放和透明的,它更多是自下而上大家共同认可的一些团队协作约定。
怎么做需求
首先必须确立一个正确的目标。没有目标在需求的选择和优先级排序时就是盲目的,小团队极其有限的资源和精力会被盲目的需求给分散,这是不可取的。所有要按照时间维度确立一个团队的正确目标,产品初期的目标应该是构建一个最小可用产品,切忌不要贪大求全,一定只坚持只做确定的、有核心用户价值的需求。产品的运营期要必需一些运营目标,运营初期的目标一定不能追求规模,要聚焦在验证产品的价值、商业模式为主,选择核心指标的时候要以选择衡量用户价值、用户留存度、用户活跃度和用户推荐度等能够反映用户使用软件的满意情况的指标,在产品价值和商业模式未验证透彻的时候就追求用户量、交易量和收入等虚拟指标会让产品走上一个不良性的发展之路。
选择的需求必须少而精。在互联网和其它自由市场的环境下,我们的用户的需求控制力较弱,因此需求的不确定性是很大的,那么我们必须选择那些确定的和核心的需求,这样才能减少我们的成本浪费,另外我们的团队较小,决定了我们没有能力做大而全的需求。另外需求量大和进度压缩严重是我们软件质量低下的根本原因,因此只有少我们才能做到精。
需求的设计应该全民参与。传统软件开发的需求往往是客户或者领导画个范围,然后需求分析人员直接将这些需求转化为软件功能设计,写个需求说明书然后就交付给开发实现。而我建议的需求设计流程是这样的,需求创意阶段是全面头脑风暴,领导、用户代表、开发、产品和运营都参与头脑风暴,充分挖掘大家头脑里的创业和想法,充分利用群体智慧获得更加全面和完善的想法,这是一个发散的过程,接下来就是一个收敛的过程,选择其中最好的需求创意,具体方法是将价值、成本和目标几个维度来衡量这些创意,尽量选择那些价值高、成本低,与目标相关性大的需求创意。而且这个过程有时候也是需要反复迭代几次进行的,指导多数人觉得满意为止。需求的设计阶段也是这样一个类似的过程。你可能会觉得开这样的会议很浪费时间,有时候可能还没有产出。但是开这样的头脑风暴和选择会议绝对是值得的,因为它能够最大程度的保证需求的质量,这个价值是很大的,一个错误的需求会导致后期的成本浪费更加巨大;另外全面的参与本身就是一个团队建设的过程,通过大家的创业和充分的讨论,让整个团队凝聚在一起;参与感才会产生认同感,只有参与了大家才会真正把整产品当成是自己的孩子,才会全情投入去做每件事情,能够充分提升团队成员的积极性,你能说这是浪费时间吗?全面参与会减少后期沟通的障碍,开发和测试人员都参与了产品的创意和设计,后期在实现的时候阻碍几乎为0,那种大家心领神会的协作真的会让你酣畅淋淋的。
需求用户故事描述和沟通。用户故事是从用户的视角来描述用户使用软件来解决问题的具体场景,用它的好处是最大程度减少了信息传递的失真,因为传统的瀑布开发模型,需求从用户到最后的开发和测试人员的时候,会因为沟通中的噪音导致误差很大,最后开发出来的软件与用户的需求偏差较大,最后导致开发中过多的浪费。而用户故事是一份最原始的信息,能够统一各岗位人员的认识。用户故事要符合这样一些特性,即有价值、独立性、可协商性、短小、可测试性、可估算性。我觉得最重要的是有价值,每个用户故事应该尽量有一个量化的价值衡量指标,比如通过这个用户故事提升了用户体验,那么如果价值得到实现,用户的转化率提升5%,只有这样我们的软件开发不是只是盲目的功能堆砌,而是逐步为用户增加价值的。
怎么开发
经过实践我特别推荐使用测试驱动开发,测试驱动开发方法是一种非常好的保障软件质量的切实有效的方法,我们经常是这么开发的,按照需求规格说明书,开始设计和编码,然后自己随便点点,只会测试几个正常的案例,如果你是一个稍微对用户有点儿责任心的人,都会觉得心理忐忑不安,对软件质量的信心肯定不足。
测试驱动方法有一个特别有说服力的例证,大家都知道瓦匠在砌墙的时候都会拉一根水平线来砌墙,这样瓦匠就不容易把墙给砌歪了,同样我们软件工程师如果这么一根线到底会怎么样呢?会不会写出质量更高的软件代码呢?
利用测试用例来预防外部质量。提倡测试先行,测试人员先将用户故事转化为具体的测试用例,测试用例是对用户故事更加准确的描述,开发人员依据测试用例进行软件设计和实现,软件开发的目的就是让测试用例能够通过,因此测试用例就是我们开发工程师手中的砌墙标线。这样按照测试用例开发能够最大程度的避免需求理解错误、需求遗漏等质量问题。
利用接口测试用例预防内部质量。内部质量(即代码质量)是我们最容易忽视的质量问题,而内部质量保障我的具体建议如果是*Unit等单元测试工具实现自动化测试,也是先写单元测试用例,用单元测试用例来描述需求,通过实现接口,让单元测试通过,再多次往返迭代过程中,若代码能够测试通过,并且代码的可测试性好,则代码的质量肯定能够得到保障,而且可以得到结构良好的代码。
代码审查。代码审查是一个非常良好的技术实践,应该坚持团队内部每日代码审查,代码审查获得的好处是及时发现和规避代码中的逻辑、性能和规范性问题,另外还能够让团队间的知识在审查中得到共享。
在实践中最大的问题是成本问题,高质量意味着高成本,这往往是很多项目在现实中难以做到的事情。那么在实际项目中,应该优先挑选那些复杂度高并且价值较高的功能或者代码进行测试驱动开发和代码审查等实践活动,比如简单的CRUD可以不做,用户界面层做自动化测试的价值不高,投入的成本非常高,则不宜采用测试驱动开发。
怎么测试
测试用例应该以用户为中心。传统的软件开发中测试人员设计测试用例会考虑从逻辑上去考虑各种分支及可能性,
怎么发布
怎么验证和改进
最后的话
写着写着,我突然发现自己的观点和经验可能与敏捷教科书中的不一样,这就是我眼中和实践过的敏捷。突然回想起原来一场大会中学到的观点,敏捷其实是一个形容词,它不是一个名次,敏捷没有终点,职能做到更敏捷,它是开放的和允许持续演进的。我认为只要是在敏捷价值观和文化的指导下,每个人都可以做出自己的敏捷。
来源:oschina
链接:https://my.oschina.net/u/113011/blog/534538