开发与设计中那些共同的隐喻

设计师/产品经理:“他会在万众瞩目中出现, 身披金甲圣衣, 脚踏七彩祥云,咔咔咔把我的设计全部实现!”

引子

偶然跟设计师同事聊天,谈到他们眼中的程序员应该是什么样的。

大叔:“好的程序员不应该三心二意,上来就学很多不同的语言,应该精通一门语言!”

小九:“那设计师会在Photoshop,Pixelmater,Sketch,balsamiq等等这些工具中,只精通一样,而不去学习别的吗?”

大叔:“这不一样,编程语言怎么能跟这些工具相提并论,比如Sketch比较适合快速实现一些Hi-Fi的高保真原型,Photoshop善于处理位图,balsamiq用于画一些Low-Fi的线框图,这些工具都是在不同情境和需求下使用的。”

小九:“我倒觉得这跟编程语言一样一样的。当需要写后台服务端的时候,我们用Java;要快速写工具脚本的时候用Ruby;要写页面交互的时候用Javascript;要写底层高性能代码的时候,用C或者C++。每个语言都有自己的特点,也有自己的使用场景。设计师应该不会说只要精通Photoshop或Sketch,其它工具就不用学了吧。怎么能为了一滴水,而放弃整片海洋!每一种设计工具都有自己独特的魅力,在学习中都会体会到不一样的乐趣 ”

语言/工具 vs 特性

熟悉PS的都知道,Photoshop中有滤镜、蒙版、图层等一系列特性,我们也往往是先学习工具,顺便就学会了这些特性。然而,其实这些特性比工具本身具有更高的复用性。现在几乎任何一款绘图软件,都会带有图层功能。

程序员也一样,往往是从语言开始,来认识语言的特性的。比如我们学习了C++,顺便知道了Template;从Java中知道了Exception的处理方法,从Javascript中知道了闭包,从Scala中知道了Monad等等。这些特性、思想在程序设计中的应用往往要比语言本身更重要。

除了语言,其实还有一些别的,也是程序员和设计师可以类比的。

思维方式

在程序世界里,有3种比较经典的编程范式:面向过程,面向对象和函数式。

  • 面向过程的编程范式,简单的讲就是把一个大的任务拆分成N多个步骤,只要一步步从上到下的实现即可。
  • 面向对象则是把所有程序中的概念都想成是一个个具体的对象,每个对象有自己的属性、行为,每个对象可以完成自己应该完成的一些事情。通过对象间的彼此互动,来完成复杂的功能。
  • 函数式则是更侧重于用数学函数的方式来思考,把现实中的复杂问题转换成各种不同类型的函数,通过数学的思维方式来解决问题。

这是程序员的三种不同的思维方式,而映射到设计师,可以理解成平面设计师习惯的平面思维和工业设计师习惯的立体思维。

模式

程序世界中的设计模式,是前人大量经验的总结,是在实战中形成的一些在面对具有一定共性的问题时所采用的最佳实践。

在产品设计中,也同样有一些模式可以遵守,比如现在的提醒功能,往往会使用内含数字的小红点模式。

再比如说消息通知功能,往往是采用消息中心的模式 。

再比如说一些常用的组件,如输入的文本框,在交互上共有诸如auto suggestion之类的模式。

有了这些模式之后,不管是在做程序设计还是界面设计,都可以有效的降低设计的复杂度。

Clean Code -|- Human Interface Guidelines

大部分情况下,我们不是一个人工作,而是一个团队工作。

作为一个程序员,我可能会阅读、修改团队内任何一个人的代码,这时候一套统一的规范就很重要,而《Clean Code》就是这么一套规范,让我们写出的代码可读性大大提高,便于团队彼此共享编辑代码。

而作为一个设计师,也有这么一套规范,比如iOS中的《Human Interface Guidelines》,或者Android的Material Design,这些规范用于指导我们在做界面设计的时候该如何选择合适的控件,应该有何种样式,如何在界面中合理的布局,并在团队中形成共识,好让大家可以在同一个工程中协调工作。

最后

综合上面说的:看起来程序员和设计师的工作好像差得很远,但其实大家做的事情是有很多相通之处的。细细体味其中的不同,可以填补之前一些unknown unknown的空白,说不定还可以给你现在的工作带来一些新的灵感。


更多精彩洞见,请关注微信公众号:思特沃克

Share

为什么不能每周发布一次?

“看,车来了!不过貌似咱赶不上这趟车了吧?”

“啊!那快点跑,错过这趟就得再等半个小时!”

……

好无奈,可是真的赶不上也没有办法,这个场景很多人都经历过。

“这个release又是一定包就开始上hotfix,四天跟了四个,我根本没时间做回归测试!” QA小静同学抱怨道。

“每次都是定包后就开始无休止的上hotfix,咱们还不如改成每周发布一次!”Dev大鹏同学也被hotfix折磨苦了。

这是发生在蓝鲸项目中一次真实而平常的对话,跟前面赶公交车的场景有什么关系呢?

发车间隔与发布周期

发车间隔的不同带给乘客的感受会完全不同。

有些公交车很少,每半个小时一趟,有时候眼看着一辆车来了又走了,没赶上会无比懊恼,下一趟还得等上半个小时,实在着急的可能会考虑叫一辆快车赶紧走。

而有些公交车发车间隔非常短,几分钟一趟,就算错过一趟也无需等待太久,只要不是着急去救火,乘客一般不会太在乎。

项目的不同发布周期带给客户的感受也是类似的。

蓝鲸项目的发布周期跟第一种公交车发车间隔非常类似,是四周发布一次。如果功能没能在这次上线,或者有导致功能无法正常工作的缺陷,得再等一个月才能再次上线。一个月,那是多少白花花的银子啊!对于那些特别重要的功能,客户着急就会要求上hotfix,于是就出现了前面小静和大鹏的对话场景。

Hotfix是否真的能解决软件交付过程中的问题呢?其实不然。

Hotfix的引入带来很多额外的工作,影响新功能的按时交付,会打乱交付节奏,有形成恶性循环的趋势。既然这样,大家一定希望能把问题解决,而且通过公交车的例子很容易想到前面大鹏说的那个方案。

如果发布周期缩短,比如说缩短为一周甚至更短,这次没上的功能也不用那么着急的通过hotfix来上线,就能解决问题。那么蓝鲸项目为什么不一周发布一次呢?

如何才能缩短发布周期?

1. 合适的迭代计划和合理的需求切分

半个小时一趟的公交车,就算车子足够大、能够承载半个小时到达的乘客数,也会导致乘客等待时间过长,造成很多不便。要解决这种情况,可以把大型公交车换成多辆小型车,增加发车次数,缩短发车间隔。发车间隔缩短到多少,车子换成多大都是需要仔细分析和考虑的问题。

映射到蓝鲸项目,要缩短发布周期,就得有相应的小规模需求正好能够乘坐小发布周期那样的小车,因此要做好发布计划和需求切分。

这样对需求源的要求很高,需要客户那头的紧密配合。要想缩短发布周期,首先必须得有足够的、粒度合适的功能需求,能够正好安排到较短的发布周期上线。如果需求范围不能提前确定好,就没法提前做好短周期发布计划,不可能把发布周期缩短。

2. 强大的开发能力

在把乘客的需求分析清楚之后,缩短发车间隔非常关键的一点就是要有足够的安全的车和靠谱的司机。如果这一点满足不了,其他都免谈。

对应到蓝鲸项目,安全的车子和靠谱的司机组成了拥有强大开发能力的团队,包括架构支撑和人员技能。

车子就是对持续交付友好的技术架构,需要减少模块间的依赖,比如采用微服务。蓝鲸项目是一个七年之久的老项目,很多陈年依赖已经形成,要拆分不是一时半会的事情,团队正在朝着这个方向努力。

司机就是我们的开发团队,除了要有必要的开发技能外,要做到靠谱就得透彻理解持续交付的精髓,需要团队中人人都有质量意识,人人都有发布周期的紧迫感,并且能够做到高效合作,从需求划分、代码质量、测试保障等做好各个环节的工作,做好缺陷的预防和监控,不让严重缺陷流入后面阶段。

蓝鲸项目由于新人较多、人员流动大等原因,质量意识和紧迫感都有待提高。不过,在各位QA的影响下,这些问题都在改善,新人的技能也在不断的学习和实践中得到提高,但仍然不能放松警惕,需要时刻保持向前的精神面貌。

3. 充分必要的测试支撑

有了足够的安全的车和足够靠谱的司机,还得保证路况够好,这样才能做到不管到达哪个站,间隔都是相同的。

要想蓝鲸项目的持续交付能够顺利前行、一路畅通,需要严格做好质量内建工作,各层都有充分必要的自动化测试保护,减少新功能开发过程中对老功能的破坏;同时持续集成流水线也要健全,不能耽误代码提交和出包,以防影响开发和测试的进度。

蓝鲸项目开发年限已久,复杂度很高,在持续交付的路上行走的有些坎坷。目前团队正在这些方面努力采取改进措施,取得了不少进展,但确实还有不少提高的空间。

前景堪忧?

过去七年,蓝鲸的持续交付之路有些坎坷,但不应因此而失去信心。

通过跟公交系统进行对比,我们可以看到蓝鲸项目要缩短发布周期、杜绝hotfix,需要从需求切分、迭代规划、技术架构、团队能力建设和测试策略调整等多方面进行优化,才能保证持续、快速的发布节奏,这是一个系统的问题。

七年之痒已经平安度过,蓝鲸团队正在采取相应的改进措施,一旦做好了上述各方面的优化,在下一个七年,一周发布一次或者更短的发布周期都将不是梦!


更多精彩洞见,请关注微信公众号:思特沃克

Share

你听说过“风格指南驱动开发”吗?

从“敏捷”下手

“今天,客户的UX又给我邮件了一版新的设计(PDF文件),改动不大,无非就是这个高度再调高点、那个宽度再调小些、这里用粗体、那边用18px的字体,可以参考以前做的手风琴组件的body部分,还有就是,顺便把手机版的样式截个图发过来?”

我:“能告诉我宽度和高度的具体值吗?那个手风琴组件可以在哪个页面找到?”

另一个开发告诉我:”先凭感觉做,然后再找UX面对面的按照要求一个个过。“

我:”好,面对面谈,总比邮件来回要快些。“

UX答复我:”面对面谈可能没有时间,你能先做一个粗略的版本吗?我先看看,然后给你反馈。等你做完所有的部分,我们再约个时间一起过”

即便心里在暗骂(等我做完了,你又跟我说这个不对,那个不对?)嘴上还是说了,“可以。”

然后,我问QA:“有测试环境可以部署我的新代码吗?没有完全做完,但是要给UX看效果。”

QA说:“有,但是部署完估计要1个多小时。”

我看了下时间,再过一个小时,客户UX就下班了,要得到他/她的反馈,估计得明天了!

当我把这个故事讲给别人听的时候,一般会得到两个回复:

  1. 哎呀,跟我们一样,痛苦的很
  2. 你们怎么这么不敏捷?

我无法否认这两个说法,很痛苦,也确实不够敏捷。但为我们提供了一点点线索——敏捷。

1-agile

敏捷宣言中强调:个体和互动高于流程和工具,工作的软件高于详尽的文档。

上面的故事很明显并不满足敏捷的价值观,邮件和截图绝对不可能代表“个体和互动”,一个需要部署一个小时才能看到页面效果的应用也谈不上“可工作的软件”。

怎么破?引入“在线风格指南”

针对当前的痛点,想要破,需要做到至少下面三点:

  • 独立前端开发工作,让它与后端逻辑解耦(俗称“前后端分离”)
  • 建立“可工作的软件”来展示前端开发结果
  • 组件化的设计和开发流程

看到这三点,明白人可能会立刻联想到一个大家耳熟能详的前端开发框架:Bootstrap。没错,它作为一个优秀的前端开发框架,确实满足上面的要求,有许多不错的网站都将Bootstrap作为网站的前端骨架。

Bootstrap有两个特质非常吸引人,优秀的特性和组件和漂亮的开发文档

不过,今天我们不谈Bootstrap框架,我想来聊聊这个漂亮的开发文档,俗称“在线风格指南”。

相信大家对“风格指南”都不陌生,主要分两类:静态风格指南和动态风格指南。

静态风格指南也就是我们常见的静态设计文档,比如,由设计师提供的PSD/PDF等文件,文档中包含:调色板,字体,按钮,链接等等。

2-style-guide

(medialoot上的一个样例)

动态风格指南,也称为Living Style Guide(“活的”风格指南或者在线风格指南),它是一个包含风格指南的Web站点,就像Bootstrap开发文档一样。

3-living-style-guide

在这里,我们需要引入的是“在线风格指南”,而不是Bootstrap,这里的不同点在于:

  • 角色变化,我们从“风格指南”的使用者,变成了是它的拥有者、开发者和使用者。
  • 用户变化,它不再是开发文档,现在用户是UX、前端开发和BA(业务分析),在UX和BA的眼中看到的文档即最新实现结果,在前端开发眼中看到的代码即设计。
  • 侧重不同,不仅仅是基础组件,也具有更加偏业务的大型组件。

为什么还要组件化的设计和开发?

组件化的做法在当前的场景下,似乎有点顺其自然,特别是有Bootstrap作为前车之鉴。

我想大家都知道,前端开发其实有一个通病,即大量的JS、CSS和其他资源文件(字体文件、图标、图片),在没有很好的管理控制下,很容易导致资源的冗余,依赖关系复杂度增加、维护性降低、导致之后的开发难度变大。

和后端语言开发不同,比如,Java有包管理和类的支持,有一些常见(或者约定俗成)的实现层次,如:Controller、Service、Repository等;有框架和语言特性带来的优势,比如IOC、AOP、注解、继承、接口等,合理利用能够让代码职责单一,模块高内聚低耦合,接口化,可重用,易于测试等等。

而Web前端开发,由于涉及到的内容较广,又不太可能完全具备后端语言的优秀特性。所以,更加需要开发人员具有优秀的设计和管理思想,比如:CSS的合理命名和管理、有效利用CSS预处理器、JavaScript的模块化、框架的特性(比如AngularJS的依赖注入,指令)、以及组件化等等。

组件化其实是大型软件开发中的一个共识,特别是前端,在没有统一标准的前提下,大家都在不断的造轮子,有无数的人倒了下去,又有无数勇士踩着前者的尸体冲上来。也许是因为它确实能够具有一些非常优秀的特性:单一的职责、资源的高内聚、独立的作用域、可独立的测试、接口的规范化、可重用、可组合等。

4-folder-structure

我们项目的代码组织结构

从“风格指南”到“驱动开发”

总结一下前面的内容,“前后端分离”,“在线风格指南”,“组件化开发”,似乎我们只说到一些与开发相关的事情,其实不然。

“在线风格指南”被开发,UX、BA共享,合理的组件划分可以合理控制开发闭环,UX可以更快的看到设计实现的原型,提升团队成员沟通频率,BA可以方便的根据组件合理的编写Story(故事卡)。

当这三个角色都参与到这个过程当中时,我们就真正回到今天的正题“风格指南驱动开发”。

这是一个相当新的术语,但不是我发明的,如果要追溯的话,最早在公开场合中谈到这个概念的人应该是Nicole Sullivan,她在2014年9月的一次演讲《Components & SGDD》中提出(Nicole Sullivan目前在NPM这家公司,没错,就是那个NPM,做Product Manager & Design Manager)。

“风格指南驱动开发”尝试着:

  1. 让UX和前端开发更紧密的工作在一起,将设计与前端开发的工作闭环缩小,更快速的迭代产品原型。
  2. 将UI开发和业务系统分离开,业务系统不仅仅是指后端系统(不仅仅是前后端分离),也包括业务的Web系统。
  3. 让设计文档更加“灵活”,更加及时(up to date),更加一致(single source of truth)。
  4. 让前端资源管理更加规范,开发模式更加清晰。
  5. 让整个Web开发周期更加敏捷(Agile)。

它是一种前端开发和团队工作方式的实践。

工作流程 – 如何“驱动开发”?

5-sgdd-process

开发流程

怎么样的工作方式,才算“风格指南驱动开发”?其实,当团队拥有了“组件化的思想”和“在线风格指南”,“风格指南驱动开发”的整个过程其实是行云流水的,我简单描述一下:

1.挖掘到新的需求/特性

当新的需求出现时,UX开始进行页面设计,Living Style Guide会作为设计的参考文档。通常情况,设计师会查看已有的调色板、字体和其他基本元素或组件来组成新的页面布局。在组件化的思想和Living Style Guide的帮助下,BA和设计师都会尝试使用或者扩展现有的组件。

2.抽象成组件

一旦设计完成,BA、UX和开发会开始讨论如何把新的设计细分为独立的组件,哪些是已经存在可以重用的,哪些是新的需用新建或者扩展实现的。Living Style Guide作为桥梁帮助设计与开发进行沟通,促进双方的理解,确保实现的准确性。而抽象出来的组件,帮助BA划分任务和故事(Story),以便更加准确的估算“故事点”。

3.实现和文档化

此时,Living Style Guide是作为一个开发框架和设计试验场(playground)。

作为一个试验场(playground),允许你随时看到每一个开发出来的组件,作为开发框架,允许你快速开发,它和真正的产品实现完全隔离,这种隔离会鼓励你以更加抽象的方式创建组件,以便于让他们更容易被重用。

Living Style Guide的开发注重组件化的隔离和规范化的开发流程(套路清晰明了),我们常常会开发一些自动化的构建任务来帮助快速初始化一个组件需要的基本内容,只要开发人员对开发所需的前端技术栈有掌握,就能较快速的开发完成相应的组件。

而开发完成的组件在Living Style Guide中立刻变成“活的文档”,可以快速展示各种不同的组件应用场景,提供给UX和BA做审查(review)。

4.组件在产品应用中的热插拔

最后一步,就是将组件应用到真正的产品实现中(该产品代码应该是与Living Style Guide毫无关系的业务代码)。而对于Living Style Guide输出的结果,应该可以任意选择刚好满足需求所需要的组件,拥有足够的灵活性,才能实现它在产品应用代码中的热插拔。

如果还有第5步的话,那就是重复上面的4步,这就是“风格指南驱动开发”的完整流程。

留在最后的思考 – 它到底驱动了什么?

作为好奇宝宝的你们和我,当读完这篇文章,应该仍然在思考,它到底驱动了什么?

6-haoqi

也许你比较熟悉TDD和BDD,他们通过测试,驱动我们编写刚好满足测试和满足需求的实现,而测试反过来成为保护伞,在我们通过重构提升代码质量的同时,保证功能的安全性。

那么,“风格指南驱动开发”到底驱动了什么?也许,它驱动着我们尽最大可能去重新使用已有的组件(代码)和设计更通用的组件,也驱动着我们(开发、UX、BA)进行更加频繁的沟通,它驱动着BA(业务分析)书写更加合理的Story,也驱动开发进行更加合理的代码和资源的管理。

Share

开发人员的客户思维

都说产品与开发之间的矛盾由来已久。在很多互联网企业,都发生过类似这样的一幕:

工程师日以继夜,终于在约定的时间里交付产品——虽然这在产品经理看来可能还只能算个高保真的原型。产品经理体验了这个原型之后,发现一些与期待不符的地方,提出了改进意见。工程师带着泛起充满自信的笑容,再次进入了封闭的开发阶段。

programmers-and-users

类似这样的过程持续往复下去,开发工程师和产品经理对对方的耐心都会受到挑战:

产品:新的方案也就是改了一种排列方式,数据都是一样的,再花点时间不就能搞定了么?

开发:你知道上次那个推荐算法,我花了多久才做出来的么?你说改就改?

产品:可我已经跟老板回复了,说咱们三天就能搞定!

开发:……

在互联网企业里,开发人员作为产品的直接生产者,地位受到优待;工程师作为“创客”所具有的自豪感及自信心也理所应当。直到随着项目的持续,业务越来越复杂,工程师终于不能在期待的时间里顺利交付功能,即使加班加点已在不知不觉中成为习惯。

开发人员与客户思维

在大量的团队里,大家表面看似春意盎然、合作愉快,实际却危机四伏。问题的原因可能很复杂,而从开发人员的角度来说,一个很重要的因素在于开发人员普遍缺乏客户思维。

2-mind

这样的开发人员也能交付能够工作的产品,但从产品设计人员的角度来说,要么他们交付的产品在细节上与需求有较大出入(或多或少,或错),要么就是花费了大量时间,却没人知道他们在做什么,也无法估计一项需求到底需要多久才能开发完成。

开发人员大多有相似的特性,他们擅长解决问题,却不擅长与人沟通。甚至一些人还有“技术至上”的自负心理,认为测试人员和业务分析师等其他角色可有可无。这或许与他们理工科的成长背景有一定的关系。“因为、所以、得证” 这是数学里常见的论证步骤,理工科的同学们擅长运用已有命题推理出一个个新的命题,这一特点在软件开发人员这里有着很好的体现。那些曾在算法练习中用过的代码片断就像一段段积木,当产品设计人员提出一个想法,开发人员就心生一计:这事儿没问题!似乎,接下来就缺时间了。

3-need-more-time

事实却不会那么简单。一个需求的提出,必然有其商业上的考量,其所在的业务场景、适用的范围和限制,以及要实现的可度量目标。在实现过程中,还需要考虑不同的解决方案,各个方案中可能存在的风险,以及需要投入的成本。在团队中,只有所有人都对业务有一致的理解,所有的努力都朝着一致的方向,才有可能获得成功。

有客户思维的开发人员,能够把工作当作为客户提供服务:自己是服务提供方,而同事、老板就是客户。他们积极地从客户角度思考需求的真正来源,在开发过程中与客户保持沟通,适时给出合理的建议。最终在更高效完成工作的同时,建立更顺畅的协作机制,培养出更健康友好的团队关系。客户思维也能够培养开发人员转变视角的习惯和能力,令其习惯于分析价值并作出决策,既而为职业和事业的发展带来更多可能。

思考并沟通

当接到一个新的需求,无论是初次提及,还是后续反馈,首先要思考的是为什么会有这个需求产生,它解决了什么问题、提供了什么价值。虽然开发人员很聪明,却很容易忽略这样一个其实很简单的部分。大部分开发人员的思维方式真的就如同数学证明那样,习惯于接受指令并醉心于实现一些看起来很酷的功能。

4-cool

然而,如果一开始不弄清楚需求的前因后果,就会出现在做了一半、甚至完成了之后,才发现最终得到了一个与设计人员的期待并不符合的产品。其他情况,由于开发团队内部理解不一致导致接口不兼容、由于前期没有沟通清楚而导致返工浪费等情况更是数不胜数。

举一个实际发生过的例子。

作为一个基于浏览器来管理的电商网站运营方,产品经理希望管理员能够在浏览器中即时收到网站用户下的新订单,而不再需要隔一段时间去刷新浏览器,以便做好发货准备。

在拿到这样的需求之后,工程师很兴奋。他开始着手研究服务器推送的各种技术,并深陷其中不可自拔,学习了长轮循、WebSocket等技术。三天过去了,他终于成功地完成了相关开发工作,急切地找产品经理要演示其进展。可没想到,产品经理却并不买账,没等工程师演示,就黑着脸向他回复,“这三天里,我两次向你询问进展,你都说‘快了’。可我一直没见什么动静。后来,我已经请旁边的阿哲搞定了,他只花了一小时!”

5-what

工程师转向阿哲,却发现阿哲用了一个每隔5秒向服务器再取一次数据的“笨方法”。工程师感到委屈不已,向产品经理解释自己的方案比阿哲的方案更有效率,也更先进……

在这个例子里,工程师自认为的高效和先进似乎并不是产品经理所关心的。产品经理作为功能设计者,自然更关心其功能价值,而不是技术方法是否先进。另外,对需求里的“即时收到新订单消息”里“即时”的理解,工程师一开始就将自己的臆测加了进去。

不妨考虑一下,需求的价值是使管理员更早知道新订单到来,但这个“即时性”要求有多高呢?显然没有达到秒级,大概,分钟级也是能接受的——毕竟之前管理员是手动刷新浏览器去完成这个需求的,这说明新订单并没有频繁到需要秒级通知。因此,不管是工程师提前想到了这个结论,还是与产品经理及时沟通了自己的技术方案计划,都可以提早防止浪费。

6-work-place

在工作中,如果只将产品经理视为规则制定者,将领导视为发号施令的老板,我们便会失去思考的机会。逐渐地,思考的能力也将失去。但如果将他们视为客户,那么就更容易理解客户与我们之间可能存在的误解,毕竟大家术业有专攻。这时,不少人便会考虑客户可能的隐藏的想法,耐心地沟通核对,态度也端正友好。

灵活地给出建议

对于一家IT公司来说,开发人员是当之无愧的宝贝,各企业为了招来优秀的工程师,都不惜重金。他们是那么的天才,似乎什么问题到了他们那儿都有解决方案。是的,其实一个用技术能够解决的问题,往往都有很多种解决方案,有些方案甚至不涉及技术。在拥有天才一面的同时,开发人员也相当的耿直,有时候甚至过于耿直,过早地将精力集中到技术方案上,而这时的方案往往还只是开发人员一厢情愿的期盼,不一定是客观上合适的方案。令人不安的是,与这些技术人员合作的业务分析人员和管理人员却没有办法预测或是验证其中的风险。

7-work

在手机支付的概念在技术圈风声水起时,有人正对“刷手机乘公交”的想法感到兴奋,在一边走一边与朋友分享的时候,正好有公交车到站。只见朋友伸出手机在刷卡机边轻轻一滑,“嘀”的一声,刷卡成功!他好奇地问朋友,你是怎么做到的?朋友淡定地翻开手机盖,从中缓缓抽出一张公交卡。

虽然这只是一个笑话,但现实中类似的情形却在真实的发生着,就像上一节中提到的例子一样。 如果开发人员拥有客户思维,就应该在真正行动之前,考虑多个可能的方案、权衡其中的优劣,及时向客户阐明这些方案的利弊;根据对需求的理解,以及客户提供的更多信息,给出具有可操作性的建议。对于一些经验丰富的开发人员来说,给出有价值的建议早就成为了他们的工作习惯,这也正是能体现他们更具专业性的行为之一。

不过,对于老油条们来说,也需要警惕:请注意保持对客户的尊重。作为客户,他们有时候显得不太专业,甚至不太友好。但开发人员,请一定尊重自己的客户。客户的最终目的是解决问题,而解决方案不一定要花哨炫酷,或是技术先进——开发人员应该在合适的时机,让客户知道他们可以做出选择,而不是由开发人员自行决定。即使开发人员自己有什么偏好,也不应该直接或间接地强加于客户,那样只会画蛇添足、招致反感。

《软技能》一书中指出了一个事实,虽然听起来有点残酷:当我们为了谋生而一头扎进代码的世界里时,其实与小时候老家镇上铁匠铺里的铁匠并没有什么区别。那样的我们,不用考虑顾客为何需要打造一件那么奇形怪状的铁器;在顾客一而再地提出挑剔意见时,我们一开始争辩,后来丧气,最后麻木了。那样的我们,数十年如一日,作为铁匠的技艺愈加纯熟。直到有一天,一种叫做“铸造机床”的远在天边的东西,夺去了我们的饭碗。

8-mechanic

如果养成了思考的习惯,拥有为客户提供专业服务的能力,随时都能换个地方另起炉灶。实际上,企业的价值正是体现在它为客户解决的问题上。习惯将工作视作服务客户,把自己当作一个企业去思考,也就具有更独立的人格,为今后真正做出良好的商业决策积累经验、奠定基础。 一旦拥有了这样的心态,开发人员也就不会只关注完成手头的工作,还知道要计划接下来的职业发展,关注自己和同事的成长;也不会因为觉得作为开发人员去帮老板实现梦想没有意义而烦燥不安。很快,开发人员这种聪明的人种就会成为有思路、有规划的进步青年。

 

更多精彩洞见,请关注微信公众号:ThoughtWorks

Share

如何实现假设驱动开发

记得我们在高中上自然科学课的时候,老师会用一个框架来帮助我们学习即基于最有效证据的实验方法。老师鼓励我们对周遭的世界进行观察,然后试着提炼一种阐述或者假设,去解释我们所观察到的东西。然后进行核对实验,我们根据理论提出一种可在核对试验中验证的假设,然后通过实验得到一个结果,如果这个结果满足假设,那就证明我们的理论是正确的。

当然,我们还可以去设计更复杂的实验,来测试和验证各种假设,然后通过更多更深入的观察结果去不断地调整,改换甚至放弃你的假设。

实验是科学研究的基础,也是探索世界的系统性手段。虽然一些实验是在实验室里进行的,但是我们也可以在任何地点和时间进行实验,比如在软件开发领域。

这里我向大家介绍一种假设驱动的软件开发理论,它是我们在思考新的想法、产品和服务,甚至组织变革的基础上实践而来的。在软件开发中通过一系列不停的实验去测试我们的想法,然后找到各种理想结果,当然这个过程是迭代的,直到得到一个理想的结果或是证明当初的想法是不可行为止。

这里需要改变一下观念,我们应该把对某个问题提出的解决方案作为一种假设,特别是在新产品或服务的开发过程中;既然我们是以市场为导向的,那么我们就应该思考这种商业模式将如何运作,这样的产品代码将如何运行,以及目标客户将来会如何使用这样的产品。

这样一来, 我们不再是做项目,而是在做实验。客户挖掘和精益创业策略,专门用来验证关于客户的各种假设。质量保证是根据要求对系统做测试。这种做实验的方式也同样应用于测试驱动开发,我们先编写测试代码,然后用测试来验证代码是否正确,如果代码通过测试,则说明没问题。从根本上说,产品或服务开发是一个过程,通过不断地测试各种关于系统行为或者我们开发的对口市场的假设,去验证最初的方案是否可行。

做实验其实最重要的结果,是可量化的证据和从中得到的经验。

这些经验是通过做实验获得的信息。我们所期望发生的事情真的发生了吗?如果没有,那到底发生了什么,以及它如何启发我们下一步应该要做什么?

为了获得这些经验,我们需要用科学的方法来调查现象、获取新知识,并纠正和整合以前我们脑海中的知识。

随着软件开发行业愈发成熟,我们现在有机会利用先进的功能,如持续设计和交付(CDD),最大限度地挖掘我们的潜力去快速地知道哪些可行哪些不可行。依靠信息发掘的实验方法,我们可以用已经定义好的产品或正在构建的服务,来快速测试解决方案。)因此,我们的目标是优化有效解决问题的效率,而不是不停地产出方案,成为一个功能和模块堆砌的工厂。

科学方法的步骤是:

  • 观察
  • 制定一个假设
  • 设计一个实验来检验这一假设
  • 如果实验成功,设定相关指标评估 (设定检验试验成功与否的相关评估指标)
  • 进行实验
  • 评估实验的结果
  • 接受或拒绝假设
  • 如果有必要,制定和测试一个新的假设

用做实验的方法来开发软件

我们要对产品和服务必须具备固定的需求这一观念提出挑战。如果团队正处于项目相对易于理解和把握的阶段,可以用已知的实践经验去得出结果,这时需求是有价值的。但如果正处于一个探索、复杂和不确定的阶段,你需要的是假设。

扔给开发团队一堆业务需求,看似加强了其对业务的认识,其实是有缺陷的

业务部门能思考并且“认识到”什么是正确的。开发团队的目标则是要实现这些内容。但是当项目进行到一个不确定且复杂的阶段时,开发团队也应该及时加入到问题的讨论和方案的解决过程中来。如果团队的开发需求都从业务这里传递,便难以发掘整个团队的全部潜力、经验和能力。

假设框架

传统的用户故事框架专注于我们想要构建什么和为谁构建,以使用户能够从中得到一些特定的好处。

作为…<角色>

我想要……<目标/愿望>

以便……<获得好处>

行为驱动开发(BDD)和特征注入(FI)通过支持软件项目中开发、测试、非技术人员之间的沟通协作,来改善原有框架。

为了…<得到好处>

作为…<角色>

我想要……<目标/愿望>

当把工作视为一个实验时,传统的故事框架是不够的。正如在在高中科学实验中,我们需要确定用什么样的步骤来达到预设的目标。然后,需要设定一些期望观察到的具体指标(或信号),去证明我们的假设是有效的。这些需要在进行测试之前设定好,以减少对结果的解释偏差。

如果观察到的信号表明假设是正确的,那么我们可以更加确信已经走在正确的道路上,并可以调整用户故事框架来反映这一点。

因此,以支持假设驱动开发(HDD)的用户故事结构将是:

b9403f84-c3ba-4d52-a87c-7c379a06681e

我们相信 <这个能力>

我们将开发什么功能来检验我们的假设?通过定义我们正在开发的产品或服务的“测试”能力,我们便能确定我们想要验证的某个功能和假设。

将导致<这个结果>

我们实验的预期结果是什么?我们通过构建“测试”能力期望的具体结果是什么?

如果能<看到一个可测量的信号>,就意味着我们取得了成功

什么信号表明,我们已经建立的能力是有效的?我们将测量哪些关键指标(定性或定量)来提供证据表明,实验已经成功,并给我们足够的信心以进入下一阶段。

用于衡量统计学重要性的阈值将取决于你对正在操作的业务和上下文的理解。不是每个公司都有像亚马逊、谷歌那样规模的用户样本,能在短期内跑出统计上显著的实验数据。因此,组织需要定义一些限制和控制等,来确定证据可接受的阈值,这将有利于团队更顺利地推进到下一步。

例如,你正在建造一艘火箭飞船,那么你会希望表明实验统计学意义的阈值较高。如果是在2个不同的用户注册流程之间选择一个能帮助增加用户注册量的流程,你可能会乐于容忍一个较低的阈值。

最后一步是清晰明显地提出关于我们假设的各种设想,为团队建立一个反馈回路,以提供进一步的输入,讨论和了解我们测试的各种情况。从技术和商业角度看,他们是否有效?

当瞄准MVP用户时,所做的假设便可以为你从产品和服务的视角提供一种测试机制。这些假设可以验证产品或服务中最不确定的领域,当然,从中也可以获取更重要的信息以及提升自己的信心。

假设驱动开发用户故事的例子:

商业故事

我们认为,增加酒店的预订页面上的图像大小

将会提升客户的参与度和转换率

如果客户量增加了5%,并且这些客户浏览了酒店图片并在48小时之内预定了酒店,就意味着我们取得了成功。

当我们使用实验方法从事软件开发时,必须要有有效的监测和评估工具,来衡量我们的努力所带来的的影响,并给团队提供一个反馈回路。否则,我们就是在盲目地去寻求努力的结果。

在敏捷软件开发中,我们将能工作的软件作为衡量进展的主要手段。

通过整合持续交付(CD)和假设驱动开发(HDD),现在我们可以定义衡量进展的主要手段为可工作的软件,和经验证的知识。

理想情况下,不应该说我们搞定了,除非已经测量到了正在提交的产品的数据值,而应该是我们已经收集到了足够的数据可以验证我们的假设了。

比如,如何收集数据做A/B测试,来验证一个假设和衡量客户行为的变化。可供选择的测试方法可以有:客户调查、构建纸上原型、用户和/或游击测试。

Lastminute.com是一家曾经和我们合作过的采用假设驱动开发的公司。该团队制定了一个假设,即预定酒店的客户只会支付在他们预定的时间内价格最高的房间。汤姆-克莱因,Sabre Holdings的首席执行官及总裁,分享了他们如何在一周内提高400%的转换率的故事

结论

结合实践,假设驱动开发(HDD)和持续交付(CD)加速了试验和增强了验证知识的机制。这让我们有机会加快创新的速度,同时不断地降低成本,以便领先于竞争对手。理想的情况下,我们可以到达一种理想的状态:细微的改变就能够确定产品和服务各种变化之间的因果关系,以及它们对关键指标的影响。

Kent Beck说,“测试驱动开发(TDD)让你有充足的理由在思考方案之前去思考各种问题”。假设推动开发(HDD)却给了你很好的机会,在提出解决方案之前,去检验对问题的看法。

Share