之前我在刚变成程序员时,对于一个网路产品怎么样建构出来。我是完全一无所知的。
当时一般比较大的网路公司是这样做的。所以假设一个产品需要六个月,以下是最常出现的时间线:
- 花了 3 - 4 個月的訪談需求
- 花了 1 個月請美術設計視覺與介面,以及反覆修改
- 最後剩下不到 两周再請 RD 进场写程式。
这种开发方式被称之为是瀑布式开发。先搜集完备规格再开工。
每周产品会议。PM 就会召集RD在会议室开会,"BrainStorming"。看看 PM 搜集到的需求,到底能不能做。
程序员往往对参加这样的会议会感到很痛苦。因为老是会出现这样的冲突:
- PM 可能觉得很容易,RD 觉得被侮辱了
- PM 觉得理所当然的功能,RD 身为重度使用者一看就知道不可行
- RD 一直枪掉 PM 的功能,PM 觉得 RD 不尊重业务专业与创意
瀑布式开发型的项目,当中的四五个月的时间,往往花在这些会议上。确保产出「完备的规格」。
等到拿到规格之后,才会再把这些规格交给视觉设计师设计介面。
设计师设计介面又需要花上几周,这期间反覆跟 PM 确认介面流程没有理解错误。
而这个流程到最后,当程序员开始接手实做时,距离上线日剩下两周时间。
这就是什么为什么多数的网络产品服务刚上线时网站都是破破烂烂的。
因为瀑布式开发型项目所有的时间,都被花在策划跟画图。
程序员面对这样的状况是很崩溃的。程序员不是不想打造好产品,但是这么庞大的产品架构,却只有这么少的实做时间。死线已经被压好了,不要说根本没有时间「写好」,光是「写完」都是奢望。
就算删掉一些没必要在第一版的功能与特效,其实也写不完。更何况在跳写的情况下,甚至「核心功能」也会不小心「被跳掉」。所以大家很常在坊间,看到刚宣布上线的完成品,结果 bug 一大堆。。。。。团队自己不满意,使用者每天都在抱怨。
这种事当然不是大家乐意见到的。改善的方式,当然是立刻抓紧时间每日加班改善。
但是,当把 bug 修得差不多之后,当初来尝鲜的使用者却已经走的差不多了。
此时团队开会检讨原因,归咎于是第一版缺乏许多市面上的核心功能,于是再度规划改版。后续团队继续努力了三个月,又奋力推出第二版。但是还不见起色,于是项目宣告 GG。
其实这样的轮回在网路创业公司,一天到晚都在上演。
然而这就是绝大多公司内部所谓的开发方式。
因为这样豪赌,一旦花时间赌输了,成本实在太大,但是又不知道有什么比较好的方式。所以我知道在大陆有些公司,为了要确保新产品上线万无一失,开发一个产品,是直接准备了三个团队一起开跑,哪个队先写好就用哪条线的产品。
当然大公司财大,可以玩这种拼命式开发的游戏。但是创业公司没办法,人就那么多。
我在参与了用瀑布式开发的两个产品后,开始隐隐约约觉得这件事不太对劲?难道流程就没办法变通吗?
一个项目真的是得收集完所有规格才能写吗?不能一边规划一边开发吗?
于是我找到一个新型态的协做方式 敏捷 Agile。有别于瀑布式开发,敏捷强调适应真实需求的快速变化。
2001年2月,Martin Fowler,Jim Highsmith等17位著名的软件开发专家齐聚在美国犹他州雪鸟滑雪圣地,举行了一次敏捷方法发起者和实践者的聚会。在这次会议上面,他们正式提出了Agile(敏捷开发)这个概念,并共同签署了《敏捷宣言》。
借着亲自并协助他人进行软体开发, 我们正致力于发掘更优良的软体开发方法。 透过这样的努力,我们已建立以下价值观:
个人与互动 重于 流程与工具 可用的软体 重于 详尽的文件 与客户合作 重于 合约协商 回应变化 重于 遵循计划
也就是说,虽然右侧项目有其价值, 但我们更重视左侧项目。
我们遵守这些原则:
我们最优先的任务,是透过及早并持续地交付有价值的软体来满足客户需求。
竭诚欢迎改变需求,甚至已处开发后期亦然。 敏捷流程掌控变更,以维护客户的竞争优势。
经常交付可用的软体,频率可以从数周到数个月,以较短时间间隔为佳。
业务人员与开发者必须在专案全程中天天一起工作。
以积极的个人来建构专案,给予他们所需的环境与支援,并信任他们可以完成工作。
面对面的沟通,是传递资讯给开发团队及团队成员之间效率最高且效果最佳的方法。
可用的软体是最主要的进度量测方法。
敏捷程序提倡可持续的开发。
赞助者,开发者及使用者应当能不断地维持稳定的步调。
持续追求优越的技术与优良的设计,以强化敏捷性。
精简──或最大化未完成工作量之技艺──是不可或缺的。
最佳的架构,需求与设计皆来自于能自我组织的团队。
团队定期自省如何更有效率,并据之适当地调整与修正自己的行为。
敏捷式开发的项目有几个特点:
- 将软件切分为不同版本,逐步开发。而非一次性讨论与开发终局版本。
- 舍弃厚重的规格,每个开发循环版本里面,只实在当版本能够对客户有价值的功能
- 保持对计画的灵活性,若发现原始方向不对,立刻拥抱变化。
- 每日沟通与测试修正,让非开发人员也高度参与开发过程,确保交付出正确的软件
- 利用流程与代码,记载软件需求,而非撰写厚厚文件。
敏捷式开发介绍了很多实用的工具,如:
- 每日站立会议(Standup Meeting) - 每日同步项目进度
- 用户故事 (User Story) - 取代原先规格,以用户真正会在系统里面完成的有价值的事去叙述架构与开发方向
- 看板方法 ( Kanban Method) - 把待办事项分为 未实做 / 实做中 / 已完成。一目了然项目进度
都是尽量在减少项目开发者的负担,并且尽量以小步快跑的方式,快速推动软件循环。
跟一般瀑布式开发很大的不同点在于,敏捷式开发的项目,往往不写规格。而是采用用户故事的方式,叠砌起项目全貌。
瀑布式开发典型的流程是 PM 花上很多的时间进行访谈写成规格,程序员再根据规格开发「转换」成功能。不过在这段过程当中,却容易出现相当大的沟通落差与实做风险。
这当中的差距在于所谓「规格」,往往强调于「画面的细节」或者是「功能的实现」,有时候叠著叠著,双方都忘记原本为什么这个功能要出现。很可能功能写出来了,却没有帮忙使用者完成任何有价值的工作。或者是功能根本就写错方向。
软件开发的目的应该是让「使用者能够在系统上完成有价值的事」。
既然如此,我们应该回归本质。
User Story 就是一种新的叙述文版,强调透过简单的语境,具体的描述出软体在「使用者」的手上,是怎么样被「操作」的。透过一个一个使用场景,整理出会在这个系统里面出现的「角色」以及「会完成的工作与价值」。
举例来说,User Story 的范本如下:
作为一个 (某个角色) 使用者,我可以做 (某个功能) 事情,如此可以有 (某个商业价值) 的好处。
这里是一些 User Stories 的范例
- 使用者可以在网站上张贴履历
- 使用者可以搜寻有哪些工作
- 公司可以张贴新工作
- 使用者可以限制谁可以看到他的履历
相单简单直观。
有一些刚开始使用「用户故事」的朋友,可能会怀疑这样的规划「太过简陋」。
其实不然,一个网站的实做价值与「主要功能」,大概用 10-20 条用户故事就可以叙述完毕了。
我认为与传统开发方式角度最大的不同,是敏捷式开发体悟到世界上的项目是活的,且是不断演化的。而产品开发的重点在于必须产出真正有价值有意义的结果。
User Story 撰写是以角色作为划分:身为「什么角色」,我要「做什么事情」。
在瀑布式开发流程中,很多时后代码会写不完是因为「里面有隐藏的角色」,比如说
部落格后台应该「要有后台管理介面」。光是有「这个后台管理介面」,背后就隐藏著「一个后台管理员的角色」,加入这个角色所需要做的动作开发量几乎就是 2 倍!(因为后台管理员可以在后台管理编辑所有文章,几乎等于要重写类似文章发表编辑的功能,只是在另外一个「管理后台」)
又比如说网路电商网站「应该要有对帐号台」。背后就隐藏著「一个会计角色」,加入这个角色所需要的额外开发量几乎是难以估计。因为对帐需求真是千奇百怪。
绝大多数的瀑布式开发,都是被这种「隐藏式功能」搞爆工作量的。
透过 User Story 方式,我们可以提早把这个项目里面「有多少角色」以及「有多少要完成的事」先估算出来。甚至把暂时把「不重要角色」要做的事先屏蔽掉。
完全可以光用几张 A4纸,就能将第一版工作量的粗估出来。后续再依项目时程人力,工作量与优先权删减迭代。
- 哪些是在头几个礼拜就要先实做的,否则会阻挡后面开发
- 有哪些功能是可以在上线前再添加。甚至是上线后再做也不迟。
- 哪些功能是完全没必要存在
这些功能将在一个一个迭代循环之中,被实做或被舍弃
我开始改用 User Story 这个方式规划软件项目后,项目的工时,几乎减少了 2/3。从六个月降到两个月。
(第一版的 User Story 可以不用很复杂)
- 使用者可以在网站上张贴广告卖币
- 使用者可以在网站上张贴广告买币
- 使用者可以在网站上看到广告下单买币
- 使用者可以在网站上看到广告下单卖币
(我们发现其实这两个流程是重复的,为了避免前期开发太过复杂,因此决定先做发广告卖币,下单买币)
- 身为一个商家,我要能够在后台上架卖币广告,并且设定上架贩卖
- 身为一个消费者,我要能够在前台看到广告,并且下单购买
(这时候明确引入角色)
(把隐藏的前期细节加入)
- 身为一个商家,我要能够在后台上架卖币广告,并且设定上架贩卖
- 使用者必须要充值数字币进来,有足够的馀额,才能够上架广告
- 身为一个消费者,我要能够在前台看到广告,并且下单购买
- 使用者必须经过身分认证,才能使用下单购买功能
(将隐藏的功能梳理出来,变成主要大功能)
- 身为一个商家,我要能够在后台上架卖币广告,并且设定上架贩卖
- 身为一个消费者,我要能够在前台看到广告,并且下单购买
- 身为一个使用者,必须在站上拥有数字货币钱包,进行充值 / 提币
- 身为一个使用者,必须经过身份验证功能,才能使用完整功能
- 身为一个使用者,为了确保资产安全,必须绑定联系方式
(这个时候,把主要的 Must Have 找出来)
(展开主要大功能,继续展开 Must Have 里面的细节)
- 身为一个商家,我要能够在后台上架卖币广告,并且设定上架贩卖
- 身为一个卖家,可以在管理后台上架广告
- 身为一个卖家,可以在发布广告时调整价格
- 身为一个卖家,广告锚定的应该是全球 BTC 行情均价
- 身为一个卖家,可以在买币者下单后,与卖家沟通进行交易
- 身为一个卖家,可以在买币者付完钱打款后,释放数字货币给对方
- 身为一个卖家,可以在买币者下单后,收到通知后,立即处理订单
- 身为一个消费者,我要能够在前台看到广告,并且下单购买
- 身为一个消费者,可以在前台看到下单广告列表
- 身为一个消费者,可以在前台看到广告内容详情
- 身为一个消费者,可以在下单后,与卖家沟通进行交易
- 身为一个消费者,下单之后,卖家数字币必须进行锁定,确保交易安全
- 身为一个使用者,必须在站上拥有数字货币钱包,进行充值 / 提币
- 身为一个使用者,可以申请一个钱包 (BTC/ETH)
- 身为一个使用者,申请钱包后,可以拿到一个数字钱包地址
- 身为一个使用者,可以充值到钱包地址(6个确认后到帐)
- 身为一个使用者,可以发起提币
- 身为一个使用者,必须经过身份验证功能,才能使用完整功能
- 身为一个使用者,必须通过 email 验证
- 身为一个使用者,必须通过 实名 验证(身份证)
- 身为一个使用者,必须通过 进阶 验证(银行卡)
- 身为一个使用者,为了确保资产安全,必须绑定联系方式
- 身为一个使用者,必须通过 email 验证
- 身为一个使用者,必须绑定二步验证
一般来说。写到第五版。一个网站大制的大骨架就会出来。
- 大骨架在完稿时大概会是 20 条上下的主要框架
- 中骨架是在大骨架下继续展开的 Must Have 功能,展开后大概会有 100 条。
- 这 100 条里面有更小的细节,最后扩展会最终会达到大至上 1000 条左右的规模。
我们会在大骨架完稿后,先做一版流程图,确定业务逻辑方向不会被这些细节冲散。
拿到主动线后。团队的主程,在开发时,并不会优先实做各个画面的细节。而是会直接把每一个大的 User Story 的画面骨干,先扑成一个完整的 Workflow。然后团队再以"重构"的方式,去补完每个画面的细节。
发布广告(以OTCBTC为例)
广告列表(以OTCBTC为例)
下单页面(以OTCBTC为例)
订单内容(以OTCBTC为例)
钱包的演变流程
重构式开发的好处,在于在第一周动工时,就有一个非常粗糙的 1.0 版本。能让整个团队成员知道目前系统有多少条确定的「闭环功能主线」,骨架非常明确,有了明确的工作方向以及工作量预估。
接著整个团队就能够以「重构每个功能画面」为目标去前进。程序员可以专注完善该功能的细节。美术设计可以专注设计该功能的画面。达到平行开发的目的。(各自完工后再整合)
当时决定做 OTCBTC 时,就已经决定要打闪电式战争。目标是得在 11/01 前上线 OTCBTC。我们是在 9/22 立项。也就是剩下不到 40 天的时间。
但是虽说如此。我们还是很乐观。毕竟此前我们做 ico 平台时,就有了区块链钱包系统的积累。所以觉得这个系统开发难度并没有想像中的大。
但第一周开始打架构,我们才发现糟了。。。。。
为什么呢?因为 OTCBTC 本质上是在做区块链版的淘宝(市集) + 阿里旺旺(买卖家即时沟通工具)。
如果真的要完整上线,需要做的功能有
- 卖家可以在上面发广告,买家可以在上面下单购买
- 买家可以在上面发广告,卖家可以在上面下单收购
- 必须支持 BTC / ETH 双币种
- 必须支持简体与繁体语系
我们当场就蒙逼了。
我们原本以为只要盖一个平台,让卖家刊登卖币的广告,让人家来买币就行了。但是经过使用者访谈后,它们不这么认为,强调完整版一定要有双向广告。
要知道,这样系统里面就有两种角色。
- 发广告的卖方
- 发广告的买方
而系统每多一个角色,工作量就多一倍。多加一个币种也是多一倍工作量,这当中的架构线图,甚至是在第一版复杂到搭不出来的。同事都崩溃了不知道如何动工。
到最后怎么解决的?
「骗」字诀!
我哄著大家,这样吧!我们上线第一版求上线就行。有事我担。第一版,只做:
- 只做卖家广告
- 只支持 BTC
- 只支持简体版
大家听了觉得这个进度应该勉强做的完,而且架构图也盖的出来(一样也是用重构式开发),就冲刺看看。
真的两周就把这个架构写得差不多了....
于是我厚脸皮的说,既然卖家广告线已经做完了。那我们反过来加买家广告要花多久时间?
同事说三天。于是我们花了三天把这个功能叠上去了。
写完之后测了一两天,确认主流程都差不多了。我继续厚著脸皮问,既然 BTC 都做完了,那支持 ETH 要花多久时间?
得到大概只是加一个下拉选单,以及修正部分显示的功夫,两天差不多。于是这时候确定上线时会有双币种了。(业界当时只有 BTC 场外工具)
时间还剩下两周多。我继续厚脸皮的问,我们可以支持繁体版吗?....
虽然我又收到很大的白眼。但是我们发现做繁体版在当时已经没有想像中的难了。因为当时我们系统里面绝大多数流程与显示字串,几乎已经完全固定下来了。繁体与简体的转换也不难。更何况,也不是每一页每一个字都需要在上线前搞齐繁体翻译。
于是我们就用这种「诡异的迭代法」,在短短二十几天,哗啦哗啦的把第一版 OTCBTC 「逼」出来了。
这种开发速度,在业界看起来是不可能的任务。
但却不是我们团队第一次挑战这类型的难题。,我们前一个项目,开发的时间略久一些,大概 45 天(第一次做区块链服务,花了比较久的时间)。用的也是类似的工法。
这当中的秘诀就在于:
- 控制难度,控制角色复杂度
- 非常早期找出真正有价值的功能,其馀尽量舍弃或变通
- 点出地图上的终点,让团队第一时间都知道最终要盖出什么
- 平行开发,没有谁挡谁的进度
我们在开发时用的方法,都不是特别复杂的方法,只是特别耐烦的一再一再迭代重构。
各位读者如果眼睛比较细,会注意到本章当中略掉了一些细节。这么复杂的系统,不可能就是写完 15 条用户故事然后自由开打吧?如果真是这样,开发现场会乱得没法形容。
是的。我们在开发过程当中,还用了其他工具加速团队协做。第一版的 OTCBTC,完成的小故事/功能,高达 600 条。下一章,我们会分享我们是如何展开以及收敛用户故事的。