编者按: 开发项目的初衷很美好, 功能需求你都理得特别清晰. 可为什么在实际开发过程中, 你的软件项目总是需要更改和调整? 最终, 添加的功能越来越多...... 要知道, 看上去很理所当然的功能列表, 实际做下去之后你就会发现事情没那么简单. 本文编译自 Medium 上原题为Your app is an onion: Why software projects spiral out of control的文章.
最开始, 你的想法很美好. 你会雇佣一个开发者来实现自己的创业点子. 但几乎每一周, 项目似乎都需要进行调整. 各种功能开始涌入, 范围越铺越大.
就好像项目被赋予了生命, 而它正在试图毁掉你的生活.
这一切究竟是怎么发生的? 你雇佣的开发者不靠谱吗? 还是你没能做好项目管理? 抑或是创意自始至终就很糟糕吗?
这都有可能. 但是有一个核心误区通常在一开始就注定了项目最终会失败.
我们假设自己的项目是由功能组合定义而成的, 我们会将这些功能记在纸上. 偶尔再添加一些功能, 偶尔又会减掉一些. 但你仍然能一眼看到项目的范围.
但是, 这种假设是错误的.
你的项目并非存在于二维空间里, 它不是一张纸. 它有自己的深度.
软件的每一个功能都可以被一层一层得剥开. 事实上, 如果我倾向于做标题党的话, 那我会直截了当得表示你的应用就是个洋葱. 让我来解释下这到底是什么意思吧. 我会告诉你, 为什么你在将自己的应用一层一层剥下时, 它会让你流泪不止.
终结所有图书馆的图书馆
我们来聊点具体的例子吧. 给我推荐一个想法吧.
人们通常想看的书, 附近的图书馆都没有. 但其他地区的人可能会有. 因此, 这款应用可以让人们发送图书需求, 而有这本书的人则会作出响应. 每一笔交易, 我们都会进行抽成.
这个想法, 很有才吧!
我知道, 难道不是吗? 功能列表非常简洁明了:
现在是时候把产品说明书发给开发者, 然后开始给公司考虑一个炫酷的名字了. kaBooki?lib.rari.ly? 还是 reddit?
欸? 别急阿. 让我们再稍微深思一下吧. 更何况, 已经有一个软件叫 reddit 了.
让我们带着下述这些问题来细究一下你的想法, 看看想法最后究竟会发展成什么样子吧.
用户如何交易呢? 他们是见面的时候一手交钱, 一手交货还是说通过应用来付款呢?
恩, 他们应该在应用上利用信用卡进行付款, 这样我们才能抽成啊.
哦...... 他们应该在应用上搜索图书, 然后挑选自己感兴趣的.
好的, 那么我们就需要建立一个图书数据库了.
我想应该是这样.
那实际上, 究竟什么是图书需求呢? 卖书的人能够看到所有的书籍需求列表吗? 还是说我们需要像 Uber 或是 Thumbtack 那样发送通知告知这些卖书的人吗?
是的, 我们需要给那些有书的人发送需求通知.
那么, 卖书的人需要在软件里填写自己要卖的书目信息吗?
恩, 是的.
那么书该如何完成交接呢? 是用户自行交接, 还是我们帮忙处理配送问题呢?
我们负责配送.
那你需要一个系统告诉你哪些书需要取货, 然后要送往哪里. 我想你的司机应该会想知道最短路线怎么走吧, 对吗?
好吧, 这样可不行. 那不如这样吧? 让用户相互之间邮寄图书.
那么, 我们就这样将收货人的地址信息告知发货人? 那我们如何解决运费问题呢?
实际上, 你知道的. 这些用户都需要靠得近一些. 他们可以上门取货, 顺便还能认识个新朋友, 这样不好吗?
所以, 我们需要匹配距离相隔较近的用户. 那他们如何找到对方呢? 应用是否还需要内嵌一个实时地图, 这样才能安排见面呢?
好吧, 这样也行. 就这么做吧.
我们需要设定图书的价格吗? 还是说买卖双方自行商定?
他们自己商定吧, 然后确定一个价格.
他们如何确定呢? 我们是否要在应用里嵌入一个聊天功能?
他们可以直接打电话进行联系啊.
好吧, 那我们是否要发送短信来确认号码的有效性呢? 如果...... 好了, 说到这儿你就应该懂我的意思了. 我们还可以这样无休止得谈下去.
别, 别再就此问题继续聊下去了.
那不妨现在再来看看功能列表长什么样吧.
每一行列出来的内容都可以多次进行延伸. 我们只不过刚刚把洋葱剥开了一层皮, 结果就已经变成这样了.
现在, 你可不要哭啊.
到底发生了什么呢?
我们要弄清楚哪些原因不会导致功能爆炸.
这也并非是我们常说的功能蔓延.
功能蔓延指的是产品不断添加新的功能. 如果你看一下我们最终的功能列表, 你会发现每一条功能的存在都符合最初的想法设定.
而这也无关乎任何技术考量.
举个例子, 什么是最适合的聊天系统架构呢? 最容易整合的支付平台是什么呢?
我们在这儿不会就这个问题多加赘述. 一个优秀的开发人员会把各式各样的技术方案都告知给你. 但是他无法帮你决定软件需要什么功能.
这也无关什么市场考量.
人们需要这样一个产品吗? 在用户数量很少的情况下, 你该如何诱使早期用户报名呢? 用户愿意为此项服务付费吗?
这类问题必须要和想法的验证, 产品市场组合的确定以及定价策略息息相关. 再重申一下, 这些问题都非常重要. 不过, 这也并非是功能列表爆炸的原因.
这与全球变暖或是牙仙也没有任何联系. 你是打算告诉我项目变成洋葱的原因吗? 还是说你打算告诉我每一条非原因项吗?
你可真无趣. 事情其实是这样的.
我们从根本意义上就曲解了复杂性的运作原理.
我们原本以为每一项功能的复杂程度就和我们一开始描述得一样. 嘿, 也许程序员是要花些功夫去写代码的, 但是用商业术语中的几个词, 你就可以轻松描述出产品的功能. 比如说 "用户用 Y 来做 X 这件事". 不是吗?
可这种观点是错误的.
软件功能更像是分形
你离得越近去看, 它们就能呈现出更多的细节.
洋葱是分形吗?
不, 我只是换了个隐喻而已. 继续说吧.
关于功能, 我们一开始是基于一个大的蓝图去进行描述的. 但是, 当开发人员在开发这款应用时候, 抑或是用户或你本人使用这款应用时, 其实它是在一个较小的规模下进行的. 它是一步一步在软件内完成的. 每一个步骤, 你都会遇到一些问题. 为了解决这些问题, 你需要重新规划这一步骤, 添加新的步骤或是添加全新的功能.
这就像是规划一条从你家到办公室的路线. 看着地图, 这段行程似乎就是两点连起来的一条直线.
但当你以更小的比例去看这条路线时, 你会发现自己原先规划的那条直线并不符合城市道路网. 你会遇到交通站, 高地或者道路阻塞. 基于你是步行, 骑车还是驾车, 你可能需要规划一条不同的路线.
开发软件也与之类似. 当你离得越近去看, 你就可以更为详细地意识到你的解决方案是什么样子的.
那可真是太棒了, 一路上都是各种细节, 这还都是我需要去考虑的. 这是不是意味着我的产品永远都完不成了?
是也不是. 之所以会显得复杂, 原因在于我们在一开始对功能进行了描述, 这通常是要实现的目标. 之后, 我们就会将其放大处理, 一步步设计解决方案来实现目标. 当我们将细节放大, 我们就会发现事情变得愈加复杂了.
复杂本身不是问题. 问题是我们选择发现复杂性的方式. 我们将功能的规格说明书递交给开发人员. 几周之后, 我们会拿到应用的初始版本并且进行测试. 这是我们第一次一步一步操作整个软件, 然后我们就发现很多的漏洞. 我们会将修改意见记录下来, 然后将其发送给开发人员, 让他开发第二版应用.
在整个过程的最后, 经过反复几次的修改调整, 我们得到了一个较好的解决方案. 问题在于, 开发周期实在是太长了. 每一个环节都需要数周或数月时间来完成,
但是, 要发现应用存在的内部复杂性, 这又是必要之举.
反反复复和开发人员进行沟通来发现这种复杂性, 耗时还烧钱.
我们希望这样做:
我们想要在写代码之前就能尽可能多得发现这种复杂性. 我们想要剥下 "洋葱" 的皮来发现一个更可靠的功能清单, 最好能以一种快速且便宜的方式.
我们并不想来回修改应用, 而是想要反复修改软件规格书.
我们想要从这个流程:
变为这个流程:
为了高效做到这一点, 我们需要两个东西. 首先, 我们需要一种方式来呈现功能列表, 以便之后反复修改调整. 第二, 我们需要一种高效的方式来审视这份功能列表.
我们来聊聊该如何实现这两点吧.
规划功能
我们不必再用商业术语来考虑这一点, 而是要把自己当做是一个用户去思考功能需求. 在这个层面上, 我们就需要应对软件复杂性问题了.
首先, 列出用户目标. 用户使用你的 app 要做什么呢?
接下来, 你需要规划用户流程. 以用户的角色确认实现目标所需要的每一个步骤, 记录下这些内容.
我们要建立一张用户使用应用的流程图.
有很多种方式可以实现这一点. 你可以简单做一个所需步骤的略图. 你可以针对用户看到的每一个界面进行版面设计. 你还可以在纸上或是用软件画出流程图.
图中是一种版面设计.
不管你选择哪种方式, 确保优先考虑速度问题. 除非你是 Photoshop 领域的专家, 否则还是放弃使用软件, 拿起纸笔来干活吧.
确保略图中能呈现出每一个界面. 举个例子, 如果一个特定的步骤需要在屏幕上以多个界面呈现出来, 那你就需要将该步骤分开. 我们希望能梳理出更多的细节.
此过程应该能揭示出应用中存在的一些复杂性问题了.
现在, 我们要开始从更深层面来挖掘了.
对一切事情保持疑问
像我们之前问的那些问题未免太过宽泛了. 这很难找到切入点.
首先, 我列出了一些适用于大多数软件的常见问题. 这些问题会被分为四大类, 你可以将其当做是模板来提问自己的软件略图.
仔细观察略图中的每一个步骤, 拿列表上的每一个问题问问自己. 如果答案呈现出了新的步骤, 就将其添加在你的软件略图里.
用户输入:
这些问题是用户在输入信息到产品中时候会碰到的.
. 用户会输入什么样的信息?
. 输入的是信息是开放式的还是交互式的?
. 开放式信息举例: 输入自由格式文本内容, 选择图片进行上传或录制视频.
. 交互举例: 往搜索框输入文本来显示可选结果, 在地图上选择地址, 从预定义选项组合中进行选择.
. 是否有些输入的信息应该被当做是无效的呢? 应用又将如何处理呢?
. 是否有无源输入呢? 最常见的例子: 通过 GPS 进行用户定位.
. 产品需要获取新用户 ( https://www.useronboard.com/ ) 的什么信息呢? 用户后续可以对信息进行修改吗?
向用户呈现的信息
如果之前那部分算作是信息输入, 那么这部分应当是信息输出.
. 屏幕上哪些信息会被呈现给用户?
. 信息是以何种方式呈现的? 比如说: 文本, 图片, 地图, 列表或图表.
. 这些信息需要以某种形式进行筛选吗? 比如说: 距上次使用时间, 用户距离, 相关性等.
. 产品是否可以主动和外界进行交流? 比如说: 邮件, 推送通知, 短信.
各部分之间的交互
这部分问题是关于软件体验中各个部分之间的交互.
. 用户会彼此之间进行交互吗? 比如说: 短信, 添加好友, 点赞或是给其他用户内容加标签.
. 用户是否会和外界服务发生交互呢? 比如说: 付费服务, 物流追踪, 社交媒体账户登录.
. 产品是否会和外界服务发生交互呢? 比如说: 位置查找服务, 天气应用程序接口, 社交网络 ("你的朋友 XXX 刚刚加入了! 查看他们的信息!")
企业家功能
这部分问题是关于企业家对于产品的需求.
. 你需要通过邮件或其他媒介发送提醒或介绍吗?
. 你需要为自己或员工提供专门的系统吗? 比如: 为配送人员提供导航软件, 为厨房员工提供实时点餐管理接口.
. 你需要手动批准用户 / 内容的接口吗?
. 你需要一个内容管理系统吗? 它可以让管理员轻松撤除内容或让用户账户失效.
还有很多很多的问题.
这就对了! 这其实也是人们通常在开发应用早期会遗忘的一些问题. 针对你的产品, 还会衍生出更多的问题, 你需要慢慢发现.
总结
建立软件略图和审核软件的过程会告诉你 -- 你漏掉了哪些内容. 重复几次这一流程, 之后你就可以更加自信地提供一份可靠的功能清单了.
你知道, 我真的希望你有什么妙招能够修缮我的项目. 可这听上去工作量好像很大的样子.
事实也确实如此. 但是这是你在软件开发过程中必须要做的事情, 不论在什么阶段.
记住我们之所以要这样做的原因. 无论如何, 你都需要发现软件功能中隐藏的复杂性问题. 你所要做的仅仅是选择何时剥洋葱.
从本质上来说, 你有两个选择:
1. 你可以发现用户目标, 构建版图设计或流程图, 质疑自己的假设, 然后像我们说得那样将软件一层一层剥开. 或者说,
2. 你可以让开发人员直接开始开发应用, 然后根据开发的每一个版本暴露的问题进行修改, 一周一次. 在几个月之后, 你就会发现这些问题, 你本可以在一周之内就用纸笔想明白的.
这也是为什么软件项目常常会变得非常复杂, 恨不得将你生吞活剥掉一般.
那么, 赶快去发现自己所需要的功能吧. 构建版图设计然后质疑自己的假设, 用一种快速且省钱的方式发现大量的问题.
此举可以将你从压力和痛苦中拯救出来, 帮助你将产品推向全世界, 让它如繁花一般恣意盛开.
洋葱会盛开吗? 你这比喻可真糟糕.
来源: http://www.tuicool.com/articles/NnARBrE