软件开发是一件相对简单的事情。客户有一定的需求,希望实现一定的价值,软件开发团队与客户合作,通过需求的分析与商榷,完成软件功能的设计与实现。说它简单是因为它专注于做好业务与技术上的事情,而不用去操心这个东西做出来干什么用,有没有用,能不能盈利。说到这里大概有些人就不同意了,说敏捷开发中强调分析和挖掘用户价值,而不是客户说什么就是什么。我想说得是,作为一个软件开发人员,直接面对的是客户,离真正的用户和实现产品价值的市场就很远了。因此再聪明的人也很难在产品价值,市场价值方面给出客户太多有价值的建议。如果真能给出,那么就不是软件开发人员的这个价钱了,而且干嘛还要给别人干,自己去创业好了。那是不是我们就不用分析业务,客户说什么就是什么,做完一仍就完事了呢,当然也不是。软件开发是一个过程,具体的说也是一份合同,我们要保证客户满意的接受我们的产品,我们能做的包括这些:选择恰当的技术和设备为客户解决问题,使得在不浪费的情况下满足业务需求;帮助客户理清他们的需求,以便于开发的进行;在进行开发的过程中仍然可以对客户的需求提出疑惑,给出建议,通过沟通得到更好的实现方式或者找出更有价值的业务部分。总而言之,软件开发是一件比较纯粹的事情。我们有业务分析人员,开发人员,测试人员,我们要知道自己每个人工作的范畴,不是各人自扫门前雪,而是要清楚自己有什么样的能力,能够快速有效的完成什么事情。
软件开发也是一件很不容易做好的事情,撇开技术快速发展给我们带来的学习掌握新知识的压力,用什么样的方法论,什么样的实践来进行软件开发也是一个很重要的课题。设计上是要面面俱到还是满足当前模块需求即可,代码需要经常修改优化还是能用就行,瀑布还是迭代,隔间还是开放式工作间。当涉及到团队合作,尤其是大规模团队的时候问题就更加复杂化了。
从传统的瀑布到现在很火的scrum,敏捷开发,这其中的演进和变化。。。我是一点没赶上。不过看看他们各自的特点和原则,结合自己简短的工作经验,多少还是有点看法。敏捷有很多原则,其中对瀑布来说颠覆性的改变是持续交付,迭代开发的概念。这也是我最认可的部分。持续的交付即能让开发人员清楚的看到目前项目的状态,因为有了持续而频繁的交付,客户能够更多的参与到软件开发的过程中来,我们也能从客户那里得到及时反馈,通过与客户的更多的沟通,也能够赢得客户的理解和支持,同时给予客户对产品的信心。
从传统的瀑布到现在很火的scrum,敏捷开发,这其中的演进和变化。。。我是一点没赶上。不过看看他们各自的特点和原则,结合自己简短的工作经验,多少还是有点看法。敏捷有很多原则,其中对瀑布来说颠覆性的改变是持续交付,迭代开发的概念。这也是我最认可的部分。持续的交付即能让开发人员清楚的看到目前项目的状态,因为有了持续而频繁的交付,客户能够更多的参与到软件开发的过程中来,我们也能从客户那里得到及时反馈,通过与客户的更多的沟通,也能够赢得客户的理解和支持,同时给予客户对产品的信心。
简单设计和重构是一对兄弟,因为我简单设计了,所以做新功能,新模块的时候代码结构就需要比较多的变化,所以我们就“重构”了。系统设计和简单设计应该说还是各有利弊的,系统设计能够给出一个比较完整的系统架构和清晰的模块划分,比起简单设计来说,能够避免太多的代码修改(敏捷称之为重构。。。);它的问题在于虽然结构很清晰,代码很少重写和返工,但是可能完全不是我们想要的东西,因为需求这个东西经过几次倒手,变成文档,再加上开发人员的个人理解,传话游戏大家都玩过,传到最后很有可能就谬之千里了。这就是为什么我们需要及时反馈和沟通。但是有个问题,简单设计有多简单,系统设计有多系统,很多时候也只是一个度的问题,还是离不了一个具体问题具体分析。
有的人喜欢隔间,觉得有自己的空间,但是个人认为开放式的开发环境对于沟通的重要性非常关键。敏捷注重沟通,从方法论到实践,无不存在着大量的,各个层级的沟通。从pair之间的随时沟通,到团队每天的站立会议的沟通,再到每个迭代的迭代会议的沟通,以及因为开放式环境给我们带来的各种各样的沟通机会。
必须承认敏捷的方法论给我们带来的很多好处,但是这些都不是白来的!因为不想做太多最后要返工的设计,所以简单设计,因为简单设计,所以代码结构会变得不适应未来需求的变化,因为不愿意忍受坏味道的代码,所以重构,因为怕重构的时候会出错,所以测试驱动开发,用测试来保证代码的正确性。可以看到我们为了做出能够真正满足需求的代码,我们要增加测试和重构的工作量。因为持续发布,所以需要持续集成的环境,除了搭建持续集成服务器的一次性工作投入,还要在每次提交代码的时候付出两次跑测试的时间(一次本地,一次服务器,还好我们项目小,也就几分钟。。。),因为持续发布,所以可以得到更多的反馈,也就是更多的工作量和变化,除了工作量本身,沟通的成本也相当客观!另外敏捷方法采用极限编程实践,比如结对编程,这就是更多的人力投入。至于好处呢,可以增加沟通和讨论,减少出错,通过switch pair可以让每个人熟悉代码的不同部分,以备不时之需。
可以看到每一个敏捷带来的好处都是有一定的代价的。还有很重要的一点,极限编程实践,比如结对和测试驱动开发,对人的要求是比较高的。除了要对自己原来的开发环境和工具熟悉之外,还要对各种测试工具熟练应用,尤其是做功能测试和集成测试,要对整个系统有着很好的把握和理解才能够写出有价值的测试(或者是会者不难?)。很多时候这些东西只会成为程序员的负累,要花比较长的时间的学习和实践才能在实际应用中得到它的好处。
再说说持续集成。一位同事跟我说道,持续集成是一个切入点,它离我们持续交付的目的最近。为了做好持续集成,首先要做好配置管理,做到频繁提交,每天都能读到别人的代码,也能够促进每个人之间的沟通。持续集成上跑的是什么?自动化构建和测试呗,所以你必须写出很好的构建部署脚本,和。。。要命的测试。又回到前面的主题,这些需要程序员个人能力的提升。
在实际的开发中遇到这样的问题。一个业务分析了半天,跟客户也聊了不少,花了不少时间,感觉差不多弄清楚了。然后开始着手写代码,写了两行之后突然发现,还是有我们的讨论没有涉及到的死角,这些死角不真正的写代码,很难被发现。赶紧问客户?客户睡了。。。想起另外一位同事提到的软件开发的反馈环理论(真会总结。。。),说道软件开发从上到下又很多个层次:用户价值,客户价值,业务分析,实际编码(具体的层次更多一些,不记得了。。。),在这个层次里,层次越高的反馈越有价值,层次越底的反馈越真实。但是两者都是我们想要的东西。。。每个层次的沟通(也就是反馈)如何进行,进行多少,真是个非常值得研究的课题。