Advanced Software Engineering, Team Structure and Development Process
软件团队和开发流程
非团队和团队
在讲团队之前, 我们要讲什么是“非团队”。王屋村里经常发生这样的一幕:
王屋村的大智要把一堆砖头从村头搬到村尾。 他到顶球酒吧前, 看到前面三三两两地蹲着一些人, 有些人前面放着一块从包装箱扯下来的纸板, 上面写着“Java, 五毛一行”;“网页前端, 不酷不要钱”;“专做 PS,擅长人体”;“通吃SQL, NoSQL”等等。
(来源: 论坛)
大智冲这些人喊了一嗓子: 搬砖的有没有? 一百块砖一毛钱!
地上蹲着的一些人抬头看了看, 有一两个人慢慢站起来了。
大智看了看人数, 又喊了一声: 中午有盒饭!
这时七八个人都站起来了, 拍拍屁股就凑到大智面前。大智就带着他们走了。
这七八个人是团队(team)么? 不是,他们只是一群乌合之众,临时聚集在一起,各自完成任务就领钱走人(work group)。
下面是一些团队的例子:
可以看出, 这些团队有共同的特点:
1. 团队有一致的集体目标, 团队要一起完成这目标。
一个团队的成员不一定要同时工作, 例如接力赛跑,
(王屋村搬砖的“非团队” 成员则不然, 每个人想搬多少就搬多少, 不想干了就结算工钱走人)
2. 团队成员有各自的分工, 互相依赖合作, 共同完成任务
(王屋村搬砖的“非团队” 成员则是各自行动, 自行独立把任务完成,有人不辞而别, 对其他的搬砖人无实质影响)
回过头想想学生在小学中学的学习过程, 虽然大家在一个班集体, 但是大部分工作都是以“非团队”的形式完成的。 大家津津乐道的“团队精神”,“集体主义” 得到了多少锻炼?
软件团队的形式
软件团队有各种形式, 适用于不同的人员和需求。第一感好用的形式未必是最适合的。例如幼儿园大班小朋友的刚开始踢足球的时候, 大家都一窝蜂地去抢球, 球在哪里, 一堆人就跟到哪里, 这是一个好的团队形式么?
要把一这群小朋友培养成一个团队(如下), 需要时间:
体育团队从一窝蜂抢球演变到有明确的分工, 阵型, 战术的团队需要时间。 类似地, 软件团队的形式, 最初是混沌的一窝蜂形式 : 一群人开始写代码, 希望能写好好软件。随着团队的成熟和坏境的变化, 团队模式会演变成下面的几种形式之一:
一窝蜂模式 (chaos team):
不能否认,这样的团队也有, 只不过他们在这样的模式下存活的时间一般都不长, 没有机会让别人很好地观察。
主治医师模式: (Chief-Programmer Team, surgical team)
就像在手术台上那样, 有一个主刀医师, 其他人 (麻醉, 护士, 器械) 各司其职, 为主刀医师服务。
也有首席程序员 (Chief-programmer),他/她处理主要模块的设计和编码, 其他成员从各种角度支持他的工作 (backup programmer, admin, tool-smith, language lawyer, specialist)。Frederic Brooks Jr. 在设计IBM System 360 的时候就是采用这种模式。
主治医师模式的退化: 在一些学校里, 软件工程的团队模式往往退化为“一个学生干活, 其余学生跟着打酱油”
明星模式 (Super-star model):
主治医师模式运用到极点, 可以蜕化为明星模式, 在这里明星的光芒盖过了团队其他人, 前一阵子喧嚣一时的“翔之队”就是一个例子。明星也是人, 也会受伤, 犯错误, 如何让团队的利益最大化, 而不是明星的利益最大化? 如何让团队的价值在明星陨落之后仍然保持? 这是这个模式要解决的问题。
社区模式 (Community Model):
社区由很多志愿者参与, 每个人参与自己感兴趣的项目, 贡献力量, 大部分人不拿报酬。这种模式的好处是“众人拾柴火焰高”,但是如果大家都只来烤火, 不去拾柴;或者捡到的柴火质量太差, 最后火也熄灭了。 “社区” 并不意味着“随意”, 一些成功的社区项目(例如开发和维护Linux 操作系统的社区)都有很严格的代码复审和签入的质量控制。
业余剧团模式 (Amateur Theater Team):
这样的团队在每一个项目(剧目)中, 不同的人会挑选不同的角色。在下一个剧目中, 这些人也许会换一个完全不同的角色类型。各人在团队中听从一个中央指挥(导演)的指导和安排。在学生实践项目或培训项目中, 这样的事情经常发生。
秘密团队 (skunk work team):
一些软件项目在秘密状态下进行, 别人不知道他们具体在做什么。 Apple 公司在研发 Macintosh 之后的系统时, 就有两三个团队在不同时期进入秘密状态开发。现在一些创业团队也是处于类似状态。 这种模式的好处是: 团队内部有极大的自由, 没有外界的干扰 (不用每周给别人介绍进展, 听领导的最新指示),团队成员有极大的投入。
特工 (SWAT) 团队:
就像电影电视中的特工组《加里森敢死队》等等影片一样,软件行业的一些团队由一些有特殊技能的专业人士组成,负责解决一些棘手而有紧迫性的问题。例如2000 年之前很多公司都需要专业人士去解决 Y2K 问题。这些团队成员必须了解传统语言和老式系统, 才能胜任这样的任务。现在还有一些团队专门做网站安全性服务。
交响乐团模式 (Orchestra):
大家看过交响乐团的演奏。我觉得有下面一些特点:
· 家伙多, 门类齐全。
· 各司其职, 各自有专门场地,演奏期间无聊天走动随意交流等现象。
· 演奏都靠谱, 同时看指挥的。
· 演奏的都是练习过多次的曲目, 重在执行。
(来源 hudong)
爵士乐模式 (Jazz Band):
我自己没看过很多爵士乐演奏, 唯一听得比较多的是Miles Davis的一些曲子。下面是一个视频, 曲子名字叫《So What》
由于我是外行, 从外行看热闹的角度, 我看到的特点是:
· 不靠谱. 他们演奏时都没有谱子
· 没有现场指挥,平时有 arranger 起到协调和指导作用(和Miles Davis 合作的 arranger Gil Evans 也是很有造诣的音乐家).
· 也有模式, Miles (姑且称之为架构师)先吹出主题, 然后他走到一旁抽烟去了, 其余人员根据这个主题各自即兴发挥;最后Miles加入, 回应主题, 像是对曲子的总结。
评论家归纳 Miles Davis 的特点是:
individual expression, emphatic interaction, and creative response to shifting contents [link] (翻译) 强调个性化的表达,强有力的互动, 对变化的内容有创意的回应 |
这听起来和“敏捷的开发模式” 有点类似。
这样的团队模式和上面的“交响乐团模式”有很有意思的对立, 但是两种模式都产生了很受欢迎的音乐作品,因此不能简单地说哪个一定好,哪个一定不好。
功能团队模式 (feature team):
很多软件公司的团队最后都演变成功能团队, 简而言之, 就是具备不同能力的同事平等协作, 共同完成一个功能:
在这个功能完成之后, 这些人又重新组织, 和别的角色一起去完成下一个功能。他们之间没有管理和被管理的关系.
大型软件公司里的不少团队都是采用这种模式。
还有一个团队模式可以叫 -
官僚模式 (bureaucratic model)
下面的模式用来表示一个机构的组织架构是没问题的, 但是把这种架构搬到软件开发中, 则会出问题。因为成员之间不光有技术方面的合作和领导, 同时还混进了组织上的领导和被领导关系。跨组织的合作变得比较困难,因为有各自老板在各自头顶上。
这种模式如果应用不好, 最后会变成“老板驱动” 的开发流程, 见后。
软件团队成员的投入
可以参见“猪, 鸡和鹦鹉的故事” 一文:
http://www.cnblogs.com/xinz/archive/2011/03/14/1983620.html
如何衡量团队成员的绩效
参见“软件工程绩效管理”一文:
http://www.cnblogs.com/xinz/archive/2011/05/01/2033927.html
思考:
团队模式和团队的开发模式有什么关系?
如果你开始一个项目, 怎么选择“合适” 的团队模式?
不同的团队模式如何影响团结绩效的评估?
开发流程
一群人在一起做软件开发,总是要有一些方式方法。就像我在概论中提到的,
我们在开发,运营, 维护软件的过程中有很多技术, 做法, 习惯, 和思想。软件工程把这些相关的技术和过程统一到一个体系中, 叫 “软件开发流程”,软件开发流程的目的是为了提高软件开发, 运营, 维护的效率;以及用户满意度, 可靠性,和软件的可维护性。 |
写了再改 Code-and-Fix
Steve McConnell 在[1] (下面的几幅图都来自于此) 里面提到了不少开发流程。第一个提到的开发流程– Code-and-Fix,看起来和一窝蜂团队模式非常像.
这个流程也有好处, 不需要太多其他准备或相关知识, 大家上来就写代码, 也许就能写出来, 写不出来就改, 也许能改好。当我们要做一些
· “只用一次”的程序,
· “看过了就扔” 的原型,
· 一些不实用的演示程序,
也许这个方法是有用的; 但是要写一个软件, 这个方法的缺点就太大了。
要注意的是, 许多学校里的软件工程作业, 就是符合上面那三点,所以难怪同学们觉得没有必要用其他的开发方法, “写了再改” 足矣!
瀑布模型 (waterfall model)
当软件工程还是年幼的行业的时候, 它从别的成熟行业 (硬件设计, 建筑工程) 借用了不少经验和模型。在那些”硬” 的行业中, 产品大多遵循 [分析 -> 设计-> 实现(制造) -> 销售 -> 维护] 这个流程。 由于在硬行业中产品一旦大规模生产, 要再返回去修改时非常困难, 甚至不可能的。因此这个模型描述了单向的, 不可逆的生产过程。
Winston Royce 在1970 年的论文“Managing the Development of Large Software Systems” (link) 第一次明确地描述了这个模型 (虽然他没有用 waterfall 这个词)。
但是要注意的是, Winston 并不推崇严格意义上的瀑布模型, 相反他指出了此模型的各种缺陷, 并提出了一些改进的办法。
例如, Winston 正确地指出了在设计大型系统的时候, 要做相邻步骤的回溯,解决上一阶段未能解决的问题:
又如: Winston 指出, 要让产品成功, 最好把这个模型走两遍,先有一个模拟版本 (simulation of final product), 在此基础上收集反馈, 改进各个步骤, 并交付一个最终的版本:
Winston 还指出, 用户的及早介入, 讨论,复审是很重要的。他建议–
Customer involvement should be formal, in-depth, and continuing.
他也提到在这个模型下文档的重要性: 下面的图中显示了8 种文档:
有讽刺意义的是, 似乎其他人并没有仔细读这个论文, 一些人看了图, 觉得很爽, 就拿来用了,而且希望waterfall 一次就把产品做好,同时产生出好些有用的文档。 一时间Waterfall 传播开来了。对于它的缺点, 一些人不正确地指责 Winston。
可以看看网友做的漫画, 看看 Waterfall 的传播和误解:
the rise and fall of waterfall: Royce Winston |
尽管狭隘定义的瀑布模型有这样那样的问题, 我个人认为这个瀑布模型还是反映了人类解决问题的一个常用的模型。它在软件工程中的局限性在于–
· 各步骤之间是分离的,(但是软件的生产过程中的各个步骤不能这样严格分离出来。)
· 回溯修改很困难甚至不可能, (但是软件生产的过程需要时时回溯)
· 最终产品直到最后才出现,(但是软件的客户, 甚至软件工程师本人都需要尽早知道产品的原型, 试用)
这个“最终产品直到最后才出现“是很令人头痛的局限性, 考虑这个制造汽车的故事:
你(用户) 提出要发动机, 车身, 车窗, 方向盘, 加速踏板, 刹车, 手刹, 座位, 车灯… 生产商按照瀑布模型流程给你设计, 生产, 六个月后交付。 看到样车后… 你提出– 我当初忘了一件小事, 要有倒车灯 § 当倒车的时候, 倒车灯会亮 生产商说: § 我要重新设计车尾部,加上倒车灯,把车底拆开,安装线路, 修改传动装置把倒车档和倒车灯联系起来。。。我得重新开始 你说: 这不是很小的一件事么?
这是小事还是大事?
|
它有适用范围么? 我认为有:
· 如果产品的定义非常稳定, 但是产品的正确性非常重要, 需要每一步的验证.
· 产品模块之间的接口, 输入和输出很好用形式化的方法定义和验证。
· 使用的技术非常成熟, 团队成员都很熟悉这些技术
· 负责各个步骤的子团队分属不同的机构, 或不同的地理位置, 不可能做到频繁的交流。
瀑布的各种变形
为了解决瀑布模型的问题, 大家在实践中提出了各种变形:
· 生鱼片模型 (各相邻模块像生鱼片那样部分重叠)
这个模型解决了各个步骤之间分离的缺点, 同时也带来了一些困扰– 究竟什么时候上一个阶段结束呢?
· 大瀑布带着小瀑布
为了解决不同子系统之间进度不一, 技术要求迥异, 需要区别对待的问题。有人引入了子瀑布模型:
在这种瀑布群下, 要把各个子系统统一到最后做”System Testing” 的阶段,难度不是一般的大啊! 但是在这样的开发流程中, 用户只有到了最后才能看到结果, 用户真是等不起。
老板驱动的流程 (boss-driven process)
在我和中国一些企业的软件开发者交流的时候, 不少人提到开发流程事实上是由行政领导主导, 或者由公司的老板驱动, 我们姑且把它命名为 boss-driven process.
(图片来源: link )
这种模式也不是全无道理,我个人认为有几个因素:
· 当软件订单的获得不是主要靠技术实力, 而是靠个人关系, 或者暗箱操作的时候, 老板的能力决定了一个团队是否能获得订单, 既然软件的具体功能并不重要(或者哪个团队做水平都差不多), 老板说做什么就做什么。
· 在大型企业内部, 软件功能往往由行政体系来决定。
· 老板比一般技术人员更懂市场和竞争。
· 软件团队尚未成熟, 不懂得如何独立地进行需求分析, 不懂得如何对行政领导有技巧地说“不”,也不知道如何说服利益相关者 (stake-holder) 同意并支持正确的项目方向。既然团队成员不能驱动, 那只能靠外力来驱动了。
这种模式当然也有它的问题:
· 领导对许多技术细节是外行,
· 领导未必懂得软件项目的管理, 领导的权威影响了自由的交流和创造
· 领导最擅长的管理方式是行政命令, 这未必能管好软件团队, 或任何需要创造力的团队
· 领导的精力有限, 当领导很忙的时候, 团队怎么办?
渐进交付的流程 (Evolutionary Delivery)
这个流程是 Steve McConnell 在1996 年总结的,但是它其实已经很接近现在大家谈论的比较多的迭代式开发流程。在系统的主要需求和架构明确之后, 软件团队进入了一个不断变化的evolution 循环中:
[开发 -> 发布 -> 听取反馈 -> 根据反馈做改进 ]
这个软件什么时候才最后完成呢? 下面几个条件满足一个即可:
· 时间到了
· 钱花光了
· 用户满意了(或者很不满意, 不再给钱了)
敏捷的流程 (Agile Process)
这一节牵涉的内容较多, 具体见几个相关的博客。
http://www.cnblogs.com/xinz/archive/2011/04/27/2031118.html (酒后的敏捷)
http://www.cnblogs.com/xinz/archive/2012/10/05/2712602.html ( Scrum/Sprint)
[1] 各种模型的图都来自于Rapid Development (1996), Chapter 7, “Lifecycle Planning” (p. 133)
----------------------
邹欣- 现代软件工程课件 在下列课程中使用: 2007 – 2011 清华大学微软软件科学实验班“现代软件工程” 2008 – 2010 北京大学软件学院“软件实现技术”课程 (部分) 2009 北京航空航天大学计算机学院“软件工程”课程 2010 - 2011 中科大微软实验班“现代软件工程”课程 |