第 1 章 善用设计原型,探索项目创意

第 1 章 善用设计原型,探索项目创意

假设你在一家代理机构工作,负责指导客户做早期产品设计和项目规划

不论做什么产品或项目,首要任务都是尽快发掘和实现客户头脑中的需求。在项目刚刚起步时,对话和绘制线框图是很有用的方法;但紧接着就应该进入探索式编程阶段,因为仅凭对话或画图能带给你的启发非常有限。

尽早生成可工作的软件,可以令产品设计变成交互式协作过程。高效的反馈环有利于快速识别潜在的不良设计,并对此提出解决方案,以免日后在更关键的阶段浪费大量时间和精力。

再简单的软件系统也是由很多活动的组件构成的,所以在设计的早期阶段就让它运转起来,看看组件之间的相互作用,是很有好处的。虽然所做的项目千差万别,但在这一层面上,所有项目都是相通的。

这一周,你将会和你的同伴 Samara 一起给一个音乐视频推荐系统开发功能原型。最初的特性集不需要打磨得多么完美,只要能实现基本功能,并从对产品感兴趣的人那里收集反馈即可。

 本章主要内容

你将学到如何运用探索式编程技术,在开发过程开始后的几小时之内为产品创意构思出有意义的概念验证方案。

1.1 从理解项目背后的需求入手

对这个崭新的音乐视频推荐系统,你闻所未闻,所以不知道应该对它有何期待。于是,你约见了你的客户 Ross,想和他简单聊聊,以便了解从何处入手。

:Ross,你好!感谢你的接待。我的开发伙伴 Samara 也在听咱们的谈话。如果你方便的话,咱们随时可以开始。

Ross:好的,我已经准备好了。第一步要做什么?

:是这样,我想先听一下你的想法。你为什么会对音乐视频推荐感兴趣呢?了解这一点可以帮助我们确定在原型设计过程中应该重点关注哪些问题。

Ross:可以,没问题。我们开了一个博客,在里面发布一些精选音乐视频列表。这个博客到现在已经开了有好几年了。我们有专业的合作方,专攻各个种类的音乐列表制作。不过,人们如果想要查看某个列表,需要手动搜索。

几年来,我们在博客上分享了 4000 多个视频,已经形成一个相当大的音乐库,但现在唯一的检索方式仍然是查找博客文章。

我们现在开始考虑怎么能更便捷地检索音乐库。考虑了几种方案之后,我们认为构建一个推荐系统之类的东西也许行得通。

最初的版本可以比较简单,但最好能尽快做出点东西来。我们想先将它呈现给几十个最活跃的社区用户和博客内容贡献者。

:这个项目听起来很不错!那咱们开始干活吧!

了解了基本主题之后,你和 Ross 又聊了几分钟,大致探讨了概念验证方案。这类项目经常需要面对的一个问题是,新系统是要作为独立项目,还是要和现有的某些系统整合在一起。

Ross 自己也不是很明确自己的需求。你提出细节问题都可以暂时搁置,现在应该集中精力探讨这个想法究竟是否可行,他表示同意。

你们深入讨论了如何设计软件原型,以便让音乐视频博客的读者更容易上手。最终,你提出了一个简单易行的解决方案:用博客搜索视频,并将搜索结果作为原型中的样本。通过这种方法,新推荐系统中的内容对于 Ross 和博客读者来说都是熟悉的,而且新的应用和原来的网站之间会有很清晰的联系,即使二者在技术层面上是用完全不同的两套代码实现的。

1.2 利用线框图表达功能需求

弄清楚几个整体性问题之后,你把注意力转回到方法论上来:如何开始项目的第一轮开发。通常在这一阶段,绘制线框图非常有帮助。你可以通过线框图向大家解释待开发应用的基本结构,同时让大家都了解需要完成什么工作,以免因过度关注技术细节而迷失了大方向。

你建议不要花费过长时间去讨论推荐系统的实现方式,而应该先集中精力寻找“最简单可行的方法”。1

1这一观点(http://pbpbook.com/wardc)由 Ward Cunningham 提出,目的在于提醒人们注意工作的最根本目标,不要因为过多地考虑收益损失而迷失方向。

:刚开始设计用户界面时,我们可以从居中前置的视频播放器这个页面入手。在播放器下面可以放几个推荐视频的缩略图,这几个推荐视频是根据正在播放的视频选出来的。你觉得这个设计怎么样?

Ross:不错,这样说好像挺有道理的。但我可能得见了实际效果才能知道具体情况。

:趁着我们聊天,Samara 一直在忙着画线框图。这张图应该能为我们的工作开个好头。稍等,我把图上传一下……

{%}

:你觉得如何?我们把问题尽量简化了,这样工作会比较好上手。

Ross:看起来还不错,跟我在别的网站上看到的视频播放器差不多。这对我们的用户来说应该挺容易理解的。

:太好了!在我们继续讨论之前,我和 Samara 想根据这张图做一个真实的网页。所有的图片都将用占位图模拟,所以做这个网页不会花太长时间。我们要用这个模拟网页测试一些基本想法,好让余下的工作顺利进行。

Ross:没问题,如果你们觉得有帮助,就去做吧。

此刻你已经鼓足干劲,但是 Samara 好像有点茫然。你问她怎么回事,她解释说,就在你拿着她的线框图向 Ross 询问反馈的那一瞬间,她脑中灵光一闪,想到了一个更好的界面设计。

Samara 提出用一种新的播放器来代替原有的推荐方式。她表示可以在播放一个视频时引入“赞”和“踩”的按钮,这样观众可以表明自己的偏好;再加一个大大的“下一个视频”按钮,点击一下就能立即播放一个新推荐的视频。这有点像看电视时的换台操作,但智能系统可以预测出接下来观众可能想看的内容。

这个新想法非常不错,但是实现起来可能不太容易。在你们稍微权衡利弊之后,Samara 同意先实现前一个简单的想法,毕竟这样能更快将真实的网页交到真人手上测试使用。

1.3 编程之初立即搭建测试系统

速成原型法的意义是拉近项目中每个参与者之间的距离:不仅是开发人员和客户之间,也包括客户和用户之间。

要达到这些目标,搭建一个人人都能使用的交互系统很有必要。这样做不仅可以鼓励大家亲自操作和试验,而非纸上谈兵,还能让大家更方便地了解你的进度。有了这种想法,你便开始进入编写和发布 Web 应用的日常流程。

由于你使用了一个正规的应用托管平台,因此这种流程无非就是用你最喜欢的框架新建一个 Hello World 页面,然后把代码推送到一个支持你所用的工具链的 Git 仓库。从这一步开始,平台就可以自行安装所需依赖项,并自动启动 Web 服务器。

尽管这个 Web 应用对应的网址有些奇怪(类似于 baby-robot-pants-suit.somehostingprovider.com),但不出几分钟它就出现在真实的互联网环境里了。

在这个阶段,你对项目完成时生产环境最终的样子毫无概念,其实你也不太在乎。为了方便从客户的目标观众那里收集反馈,你会构建一些考察性的特性,这部分代码在产品完成上线之前就会被移除。

你把 Web 应用的基础结构部分中能砍掉的都砍掉了,甚至连数据库系统都暂时没有建,因为现在还不清楚是否需要。你玩的就是“大规模投资不足”,而且你还玩得不错。

“我们用不用给网页弄些自定义风格什么的?”Samara 问道。

你想了想,却想到了 YAGNI 原则,2 然后答案就明朗了。

2YAGNI(http://pbpbook.com/yagni)即 You Aren't Gonna Need It(你不需要它)。这是一种设计原则,旨在告诉设计人员不要添加任何不必要的功能。

你回答说:“不用。如果这个原型是为营销演示做的漂亮的软件,我们一开始就会重点关注它的外观。但对于目前的情形,我觉得 Ross 只是想把原型给几个朋友看看,让他们就功能方面提提意见。这样说来,因为它只是一个简单的视频播放应用,所以界面可以尽情精简,简到极致。”

这次 Samara 好像彻底服了,虽然你又一次“不修边幅”,删繁就简。不过你们一起工作的时间够长了,如今已经习惯了;很多情况下,Samara 也会为你指点迷津,防止你把事情想复杂。

你花几分钟搭建了一个你常用的 CSS 框架,同时 Samara 把一些占位图拼凑了一下。这些工作做完后,你写了一些简单的 HTML 代码,把图片和一些编好的标题对齐到网格。

你纠结于歌曲名称到底应该放哪儿、字体具体设多大,在这上面花的时间有点多。但是你马上想到了很重要的两点:第一,目前这些细节根本无关紧要;第二,该吃午饭了!

你直接按原样部署了代码。过了一分钟,网页就发布到网上了。

{%}

这个网页看起来实在是毫无特别之处。你开始担心客户理解不了为什么给他看这么简略的网页。

为了验证自己的想法,你问 Samara 怎么看。她指出,再简单的设计第一次见客户也免不了遭遇意见,但再丑的媳妇也得见公婆,这样说来晚见不如早见。

这下你放心了。你提醒自己,第一次发布的真正目的是创建一个可用的系统,以便提高后续的变更速度,并由此开始探索项目创意的过程。从现在开始,客户可以直接和你编写的软件交互,这将大大提高你的开发速度。

你给 Ross 发了一条消息,告诉他你做好了一个页面并请他过目。然后,你休息了一小会儿,等待 Ross 的回复。

1.4 全面探讨不足,改善追求实效

你回到办公桌前,看到 Ross 已经把反馈消息发过来了。

程序员朋友们好!

我刚刚试了一下这个页面。在我的笔记本电脑上,页面看起来和你们给我看的草图差不多,这没问题。

我又在手机上试了试,但页面看起来就有点别扭了。视频和屏幕一样宽,而且下面的推荐视频被排成长长的一列,而不是并列的一行。

我们绝不是希望刚一开始就让这个页面看起来多漂亮,但是至少可以让所有的推荐视频尽量在一屏里显示完整,而不是需要往下翻,去看一个又一个完整大小的视频。

你们觉得这个问题好解决吗?

Ross

和 Samara 料想的一样,虽然第一次发布的页面已经简单到极致,但还是有问题浮出水面了。完全不犯错误是不可能的,但最关键的是你对这些问题作何反应。

你知道自己不能逃避手机界面的问题,但也不打算对它进行深究。对这个问题比较合理的回复是绘制一张新的线框图,然后解释一下正确渲染时页面应该是什么样的。

Samara 开始在自己的手机上浏览一些比较流行的视频网站,发现其中有好几个用了同样的布局。她随后画了一张差不多的草图,但只留下了其中最基本的元素。

{%}

你把线框图发给了 Ross,然后花了些时间跟他讨论接下来的几个步骤。

Ross:谢谢你们的图!这可以说是一个很好的开始!

:很高兴听到你这样的评价。有件事需要我们现在决定一下:我们是马上修复手机布局的问题,还是以后再说?

我和 Samara 觉得还是先实现一些有用的推荐功能,再回头考虑界面问题比较好。

虽然这么说,但如果你认为即使是在收集反馈的阶段,手机界面的友好程度也很重要,我们可以在继续之前先解决这个问题。

Ross:如果拖得越久,这种问题是不是越难解决?

:我觉得不会。推荐系统的大部分工作是在后台进行的,所以界面不需要改太多。而且如果我们真要对主界面做什么重大改变,手机界面还是需要推倒重制。

Ross:那好,这个问题就暂缓吧。不过,如果早期的测试用户抱怨说这东西在手机上用起来不方便,我可能会改变主意。但是先不用担心,我们可以等到开始收集反馈时再说。

每当发现自己的软件有瑕疵时,你可能想要停下手中的工作,立即去修复。但是在项目的探索阶段,你得去平衡软件缺陷带来的损失和修复这一缺陷的时间成本。

在这种情况下,推迟修复手机界面小问题所节约下来的时间,可以用来研究音乐视频数据集,并尝试构思一些推荐规则。但这时你可以就修复问题提出一些粗略的计划,并和客户交流想法。这样一来,你就在没有投入太多精力的情况下提前排除了此问题可能带来的一些风险。

1.5 早问多问,验证设想

从之前的谈话中可以看出,Ross 只是想为自己的音乐社区做个好玩的东西,这比较容易实现。幸好他没有要求“给我做个全世界最高级的推荐型音乐播放服务出来”,也没有提出诸如此类的要求。

不过,验证对这种事情的设想总是有好处的,而且越早验证越好。最初的线框图主要关注用户界面的外观,而现在是时候讨论一下系统如何工作了。

:现在我想问一个技术性更强的问题……

我们在实现推荐功能时,应该采用什么规则呢?

Ross:哦,这个嘛……我其实希望你们对此能有些见解。几周之前,我们甚至根本没想到这个项目值得去做,所以对它没什么研究。

:其实有很多方法可供选择,从最基本的类别匹配到非常高级的机器学习算法,不胜枚举。选择什么方法要看具体情况。虽然不管怎样我们都能帮助你做这个项目,但我们真的不太擅长选择推荐规则。

Ross:我们的博客文章内容都是特别细化的精选列表(如“你可能从未听过的 10 首 Miles Davis 乐曲”“20 世纪 80 年代纽约嘻哈现场表演合集”“最受喜爱的圣诞季家庭音乐”),不知道这点有没有帮助。

我们希望要做的这个推荐工具能帮观众在众多列表之间快速切换,直接找到自己喜欢的音乐。比如,他们可能正在看一段 20 世纪 80 年代纽约嘻哈现场表演的视频,然后这个推荐工具就能找出同一位艺术家的其他作品,或者找出同一时代的其他嘻哈音乐作品,诸如此类。

:好的,这给了我们一些启发。谢谢你。我觉得我和 Samara 可能需要消化消化,思考思考,然后明天做出一些东西给你看看。你觉得可以吗?

Ross:当然没问题!感谢你们所做的工作,非常有意思。

从这次对话中能够确定,一个简单的推荐系统应该就足够了,因为 Ross 在细节实现方面的需求很灵活。你这次算是走运,但如果下次客户头脑中有什么复杂的想法,早问总比晚问好。所谓“学之乃知,不问不识”,多问问总不会有坏处!

1.6 力求缩小自己的工作范围

从开始到现在所做的所有工作,还只是在为项目寻找一个切入点,而现在是时候撸起袖子加油干了。目前还有诸多未知因素亟待确定,你花几分钟研究了 Samara 之前画的草图,提出了很多关于细节实现的问题。

这些问题一股脑儿地涌入你的脑中,让你毫无头绪。但是如果不想办法为这些问题排出优先级,就没法进行下一步的工作。

在你和 Samara 发现的这 5 个重要问题中,有两个似乎比较容易解决:如何为视频生成嵌入代码,以及如何获取缩略图。

你找出了 Ross 管理的音乐博客,看看他用的视频托管平台是什么。你又点开了几篇博客文章,查看它们的源代码,研究其组织结构。

“大部分文章都直接嵌入了 FancyVideoService 里的视频。嵌入代码的格式是标准的,区别不同视频只需要依靠每个视频唯一的标识符。”

“那缩略图呢?是什么样的?”

你犹豫了一会儿,然后试着点击了博客里的几个静态的视频缩略图链接。由此确定,这是一些哑链接,点击它们并不会转到任何地址。

“这个网站好像根本没用真正意义上的缩略图。目前来看,所有内容都是来自别的网站的内嵌视频,所以估计我们得查一下。”

你在网上搜索了几分钟,想查查怎样抓取 FancyVideoService 视频的缩略图,但是并没有找到任何与此相关的官方文档。不过,你找到了一篇博客文章,里面描述了 FancyVideoService 使用的内部 URL 格式。因此,只需要从音乐博客的视频嵌入代码中获取视频的标识符,再套到这个格式里,就可以很容易地生成视频链接。

于是,你根据音乐博客里的视频,手动生成了一些缩略图 URL。它们看起来能正常工作,但无法确定在实际使用中这种做法是否行得通。现在你的态度比较乐观,但在项目收尾之前还得和 FancyVideoService 联系一下,确认这种做法是合法的。

扫除了这些障碍,现在你可以重新关注在审查草图时发现的一些更主观的问题:抓取音乐视频需要什么数据,如何存储这些数据,以及如何用这些数据生成有用的推荐信息。

你和 Samara 开始讨论可行的方法,但很快就发现你们对细节关注得过多了。所以,你们又回到了那个经典问题:“最简单可行的方法是什么?”

沉思了一小会儿后,Samara 突然灵光一闪。

“我们先从艺术家匹配做起,怎么样?根据正在播放的视频,我们随机抓取同一艺术家的几个其他作品。”

“好主意。虽然最终 Ross 用来收集反馈的版本需要比这个复杂一些,但我真的手痒痒了,想现在就做个交互页面出来试试。”

艺术家匹配是一个非常容易的切入点,因为需要的信息仅仅是 FancyVideoService 上的视频标识符、歌曲名和艺术家名。从 Ross 的博客中抓取几十个视频,就可以作为很好的样本数据了。

“那存储方面该怎么办?我是不是应该准备一个……”

你还没说完,Samara 就打断了你的话,因为你忘了 YAGNI 原则。

“现在还不需要,我们现在把测试数据集硬编码一下,生成一个队列,然后遍历这个队列就可以得到推荐数据了。”

“这花不了多少时间吧?”

“没关系。做这个工作不用花太多时间!”

Samara 已经准备就绪,所以你把编写代码的工作交给了她。同时,你去整理视频,把一堆歌曲名、艺术家名和视频标识符对应到一起。

15 分钟后,你们俩已经做出了一个像样的半成品,3 并把它发布到了网上。

3图片来源:钢琴(http://pbpbook.com/piano);Regina #1(http://pbpbook.com/reg1);Regina #2(http://pbpbook.com/reg2);Regina #3(http://pbpbook.com/reg3)。

为了展示工作进展情况,你在这一天结束前给 Ross 发了最后一条消息。

:嘿 Ross,你现在可以看一下那个网站。我们已经加了一些功能,它现在看起来像个音乐推荐系统了。系统现在实现的功能非常有限(只能进行艺术家匹配),但我们还是想给你看看,应该挺好玩的。

Ross:哇!做得真不错!交互的感觉的确比呆呆地看着一堆占位图好多了,而且做出来的这个效果几乎和我设想的一样。

我猜你俩明天会添加一些更有意思的推荐行为吧?不需要做得多精致,但估计会比艺术家匹配复杂点儿吧?

:没错。我们还在考虑具体加什么,但是明天做出东西后会展示给你看。

Ross:太好了!再次感谢你们所做的努力。我非常高兴能在工作开始的第一天就看到这个想法的雏形。

你和 Samara 做出来的这个“行走的骷髅”4 在今后的版本迭代中会变得越来越有趣。

4“行走的骷髅”(walking skeleton,http://pbpbook.com/skel)指的是以端对端的方式小规模实现某个特性。它可以作为项目的一个很好的切入点,有助于设计和演化系统的剩余部分。

第一天所做的大部分工作是搭建一个基本框架,因此接下来的开发工作就会变得相对容易。你可以在这个已有的框架中发掘真正的问题,并试着去解决。如果一开始就直接考虑整个问题怎么解决,你就会很难找到一个切入点,这样停滞的时间就会更长。

一天的时间已经所剩无几,你决定利用下午时间解决一些小事,上网读读博客,再用手机玩玩小游戏。

1.7 谨记原型并非生产系统

在拖延了半个小时后,Samara 打破了眼前的平静。她带来一个激动人心的消息。

“快看,FancyVideoService 的客服给我们回信啦!”

“是吗?我都不知道你给他们发邮件了。你什么时候发的?”

“你和 Ross 谈话的时候。我想着这种事早联系比晚了好,但没想到这么快就能收到回复。”

你在她身后看着屏幕上的邮件,里面写道:

您好 Samara,

针对我们托管的视频,用热链接访问缩略图,这在技术上不违反我们的规定,因为我们很希望自己托管的视频能够通过各种渠道被大范围分享。

虽然如此,但我们没有正式支持这种链接方法,所以不能保证视频 URL 的生成方案一直不变。同时,我们有权禁止任何可能滥用服务的行为。至于何种行为属于滥用,我们保留判断的权利。

更好的方式是在我们的开发者社区注册一个账号,然后使用我们提供的数据 API 作为访问接口。以这样的方式查询缩略图 URL,即使我们更改了 URL 的结构,您的代码仍然能正常工作。

注册开发者账号的另一个好处是,如果您在不知情的情况下违反了我们的服务条例,我们会马上进行通知,并给您提供帮助来解决这一问题。

希望以上内容对您有所帮助,祝您“精彩”(Fancy)每一天!

Sarah

得知所用的方法可行,你便放心了,虽然你用的并不是 FancyVideoService 提供的标准方案。

为了节约时间,你决定先用不受官方支持的方法来生成缩略图 URL。但是你做了标注,好让这一模块的后续开发人员知道有这么一回事。

今天的进展不错,于是你开心地回家了。

1.8 巧妙设计特性,轻松收集反馈

第二天一早,你刚到办公室,就发现前一天晚上还空空如也的白板上已经贴满了便签条。Samara 在干什么呢?你很好奇,于是开始研究那些便签条的内容。

“哇!Ross 肯定会爱上这个的!你今天早上几点来的?”

“大概一个小时之前。这个点子是我吃早饭的时候想到的,于是我就决定赶紧过来实现一下看看。”

Samara 看起来有些疲惫,好像没睡够觉,但是你看到她的点子后太开心了,觉得没必要提睡觉的事情。

“那么,我们现在开始做这个吧?我觉得这个想法大有前途,而且你的便签条写得太好了。”

“已经做好了,自己看看网站。”

你坐下来,花了几分钟尝试那些新特性。全部运行良好,尤其对于第一次更新来说已经很不容易了。

“做得这么快,你是怎么做到的?我猜你和往常一样,在实现的时候精简了一些细节。但是即使这样,让我来做的话估计一个小时也做不完呢。”

“哦,你绝对不想看这部分代码。看到这一堆推荐评分了吗?我把这么多东西全存到同一个浏览器 cookie 里了。”

想要做到张弛有度,知道什么时候该快、什么时候该细,是需要经验的。不过你相信 Samara 的判断。你又联系了 Ross,让他查看一下新特性和提供一些反馈。

:嗨 Ross,很高兴我们又做了新东西给你看。请你抽空去看看那个网站,看完后我再给你讲解一下。

Ross:那我尽快看看,多谢。真没想到你们在午饭前就能给我回复,这真是个惊喜啊!

:这儿有一张截图。5 你看过一些视频后,网站就会是这个样子。请一定亲自感受一下真实的效果。:-)

Ross:刚刚花了几分钟尝试新特性。真是太棒了!

我注意到“感兴趣”那个侧边栏,昨天我们都没讨论过。能否解释一下它有什么作用吗?

:没问题。先说明一下,我们现在添加这个侧边栏,并不意味着以后它必须成为界面的一部分。

因为推荐系统的工作原理不太好解释,所以我们就做了这个侧边栏,以便形象地向你展示用户在选择视频的过程中,应用是怎么给标签评分的。每个标签都可以点击。如果你点击某个标签,系统就会随机选出对应分类中的一个视频。你可以通过这种做法改变评分,进而改变推荐行为。

Ross:能给我演示一下这个怎么用吗?

:当然可以。你可以多点几次 Thelonious Monk 那个标签,看看会怎么样。

Ross:啊!我点击完之后,反民谣音乐 6 被推荐得越来越少,而爵士乐变多了。最后,系统给我推荐的视频只剩 Thelonious Monk 的了,我猜这就是你们的用意吧?

:没错。现在感觉明白点了吗?

Ross:我觉得已经很明晰了,而且还想多试一会儿。另外,我感觉这个系统已经足以示人了。我想今天就把它发给几个人看看,收集一下其他人的反馈。

你们做的这个侧边栏真的非常非常好,因为我如果只听你们的描述,可能很难理解推荐系统的工作原理。真的很感谢。

:这主意是 Samara 想出来的。我们真应该好好做做这样的功能,因为这有助于理解后台行为,而且你能有机会研究一下我们实现的规则。

* * *

Ross:我再问一个问题就把网站发给别人看:样本数据是从哪里来的?

:目前我们还只用了很少的数据,是从你的博客里手动挑出来的。但是我们打算好好研究一下选数据这个功能,好让你能自定义数据。

系统现在是从一个 CSV 文件里读取数据的,你可以通过表格软件编辑它。你看一下,这是目前系统里的一些记录。

:第 1 列是每个视频的标识符,出现在 FancyVideoService 视频 URL 的结尾。第 2 列是艺术家名,第 3 列是歌曲名。后面的每一列都可以任意作为标签。现在我们只定义了两个标签(流派和发行年),你可以自己再往后添加标签,想加多少加多少。

Ross:等一下……你看我这样理解对不对:如果你把这个表格发给我,我编辑这个表格,随便往里面加视频,然后你可以直接导入我加的视频,连同标签显示在系统里?

:没错,基本的想法就是这样。刚开始的时候可能要编辑得谨慎一点,因为这些内容的格式一定要正确,但是我们可以适时为你提供帮助。

我们现在的想法是,你再从博客里挑出几百首歌做成一个列表,这样就能对现在的推荐行为进行更实际的测试。

完成这一步之后,我们就可以商讨一下如何把你所有的 4000 多首歌从博客中自动推送到系统里。但是我们觉得这个问题不着急,可以稍后再考虑。

Ross:太好了。我马上就按你说的做,从博客里选一些歌,然后做一个不太长的歌曲列表。弄完之后,我争取今天让几个人看看你们做的系统,下午晚些时候我应该就能把他们的反馈告诉你们。然后我们就能知道下一步应该重点关注什么问题。

我真的不知道该怎么感谢你们。你们做得太好了。

:做这个项目很有意思,而且你对我们帮助很大,让我们做起来轻松很多,所以也要感谢你。

5图片来源:Ella Fitzgerald(http://pbpbook.com/ella);Beck(http://pbpbook.com/beck);Thelonious Monk(http://pbpbook.com/monk);Regina Spektor(http://pbpbook.com/reg2)。

6反民谣(antifolk)是一种结合民谣和朋克的音乐形态。——编者注

虽然你们互相表达了感激之情,但接下来并不一定会一帆风顺。俗话说“细节决定成败”,随后的几次迭代会涉及更多细节。在原型阶段结束之前,应该至少会有一个始料未及的重大问题浮出水面。

但出现这样的情况并不意味着开发过程有问题,你恰恰应该做好准备面对反馈环的加速所产生的这一副作用。原型可以帮助你更快地做出有用的产品,但也可能让你失败得更快。如果不用花太多时间就能辨认出死胡同,那你就有更多的时间和精力去寻找正确的路。

不过眼下,你和 Samara 都很满意,打算庆祝一下初步的成功。在项目早期建立起一些诚意和信任,可以给人一种动力,让人在啃到任何创新工作都无法避免的“硬骨头”时,能够坚持下去。

忠告与提醒

  • 多向项目参与者提一些能够发掘其目标的问题。这样一来,你既可以验证自己的想法,又可以更好地了解他人对问题的看法。
  • 绘制线框图(草图)可以清晰地和他人探讨应用的结构,不会因为被样式细节绊住而停滞不前。
  • 一定要在一开始写代码的时候就搭建一个测试系统,让大家都能与其交互。测试系统不需要完善到满足上线要求,只要适合收集有用的反馈即可。
  • 在项目早期,集中精力解决有风险或未知的问题。建立原型是为了探索问题空间,而不是为了做出完整的产品。

 

问题与练习

问题 1:本章中的音乐推荐系统开发工作进展得比较顺利。是否存在可能会出问题(但在本章中没有)的环节,使开发工作变得更为困难?

问题 2:在本章中,开发人员为了顺利开展工作砍去了很多细枝末节,请举出两个例子。在这些决策中,开发人员是如何权衡利弊的?换句话说,开发人员为了换取速度,放弃了什么?

问题 3:假设客户不满足于简单的推荐系统,而是想实现一个涉及机器学习算法的高级系统。那么原型阶段的方向要作何改变?

练习 1:绘制几张线框图,描述一下维基系统的基本功能。然后重复该过程,但这次画一张不同界面的图。思考二者在实现细节方面的不同。

练习 2:随便找一个你最近用过的软件工具或访问过的网站,假设自己现在要把它从零开始实现出来。用不到一小时的时间思考前几步该做什么。

哇,你已经读完了第 1 章!太棒了!

请尽情享受以下这个无关主题的解谜游戏,7 将它作为我对你努力的肯定吧。

7解开这个谜题不需要写代码,但是请准备一张 ASCII 码表,应该会用得着。一旦你掌握了这个游戏的规则,用纸和笔几秒就能找出答案。

{%}

从头开始做,“砰”地一下就能做出来! 8 必要时在表中进行跳转,但是不要被其中的噪声字符所迷惑。如果你仔细观察,一定能猜出其中的隐藏信息。

8这是双关语,亦表示从左上角的“>”符号开始,遇到“!”终止。——译者注

目录

  • 版权声明
  • O'Reilly Media, Inc.介绍
  • 前言
  • 第 1 章 善用设计原型,探索项目创意
  • 第 2 章 观察增量变更,发掘隐藏依赖
  • 第 3 章 准确识别痛点,高效集成服务
  • 第 4 章 设计严密方案,逐步解决问题
  • 第 5 章 谨记自底向上,优化软件设计
  • 第 6 章 认清现实瑕疵,改善数据建模
  • 第 7 章 逐渐改善流程,合理安排时间
  • 第 8 章 认清行业未来,再议软件开发
  • 作者介绍
  • 封面介绍