需求的冰川

在面对客户、面对用户或是面对五花八门的产品时,我有时会忍不住问自己,到底什么是需求分析?这概念好像哪哪儿都有、无人不知无人不晓,又好像深不见底难以摸个透彻。那我们在谈论需求分析的时候,都在讨论些什么?

要谈论需求分析,先要说说需求本身这个概念。在我们的语境中,需求往往包含了两层意思:

  • 用户需求:从用户自身角度出发产生的“自以为的”需求
  • 产品需求:由综合提炼用户的真实需求而产生的符合组织和产品定位的解决方案

这样一来,重点显而易见:真实需求和解决方案。如何挖掘需求、如何确认需求和解决方案我们已经有了很多成熟的方法论。但真实的需求又是什么?如何知道我们拿到的就是所谓“真实的“需求?要想摆脱需求罗生门,无限接近用户真正的需求,让产品从能用到好用,恐怕第一大忌就是“想当然”。

“想当然”,很大程度上等于我们经常在讲的making assumptions。做合理的assumption并积极地验证假设从来不会造成问题;可怕的是没有意识到assumption的存在还自我感觉良好,这大概就是我们中文里“想当然”所包含的意思了。

拿到我们的项目交付语境中,“想当然”是什么?是懒做甚至不做用户调研关起门来做需求;是自以为了解用户也了解客户没经过验证就敲定了需求;是偏听偏信客户爸爸的话说什么就做什么。

用户研究与验证

了解用户/客户是个庞大的课题,当用户体验被不断强调,可能没有人会跳出来否认用户研究和验证的价值。但反观我们的实践,很多时候业务分析师在需求层面上对用户研究和验证的重视还远远不够。

造成这种缺失的一大原因在于角色的割裂。有人理所当然地认为用户研究与验证是设计师的事,毕竟他们的头衔才是“用户体验设计师”。在产品同质化严重的今天,“体验”二字包含的不单是界面好不好看,操作顺不顺畅,更是背后的业务逻辑和痛点把握。如果强行将需求分析和用户调研分割开来,我们所做的需求分析很可能是浮在真相表面的“假需求”,所谓用户体验更是无从谈起。

业务分析师常常被形容为产品和交付之间的桥梁,产品经理把握产品走向,聚焦产品成长;业务分析师则往返于产品经理和程序员之间,专注如何迅速有效地让产品落地。于是,有人理所当然地把用户研究与验证的锅扣在产品经理头上,认为他们作为产品的最终负责人,应该由他们去做用户反馈的收集,再传递给业务分析师。

首先,我们应该承认产品的需求和运营是无法独立存在的,如果业务分析师和产品经理是纯粹的上传下达关系,分析师既不接触用户也不关注反馈,他甚至连“好”的定义都模棱两可,如何能分析好需求又怎么做好一个产品?其次,虽然产品经理们对自己的行业和领域有很深的了解,但对产品的规划设计和交付却很难面面俱到。他们不是不愿意做好用户研究与验证,而是不一定具备这种能力;即使做好了,也很难知道如何准确地把合适的信息传递给业务分析师和交付团队。

我们不止一次地强调“复合型人才”对产品构建和组织转型的重要性,在需求分析领域,用户研究和验证或许是呈给业务分析师的第一份考卷。

“了解用户”无法一劳永逸

在没有直接接触过用户、也没有参与过产品前期设计活动的时候,我曾经想当然地认为“了解用户”是售前团队、产品探索和规划设计团队的事情;我作为交付阶段的业务分析师,只要跟着项目计划保证交付就好了。后来有机会接触了更多项目更前期的阶段,开始认识到事实也许并非如此,但也并没有付诸实际行动。原因再简单不过:项目交付已经焦头烂额,花“额外的”精力去做用户研究和验证只能带来眼见的工作量负载而非立竿见影的成效,更别说有招致需求膨胀的可能,不如作罢。

在产品探索和规划设计阶段,由于时间紧、任务重,我们的用户研究与验证往往侧重在产品概念层面,确保产品方向性的正确。因此,即使在产品快速启动时产出了完整的需求列表和设计,也不意味着他们统统是ready to go的状态;更不意味着在交付的第二期、第三期,可以照搬当时的产出作为产品目标。“了解用户”无法一劳永逸,反之,它应该是持续的:在产品进入稳定的交付阶段后,业务分析师应该继续积极了解用户,不断验证并挖掘需求;用户和环境都在改变,该重新组织产品规划设计工作坊的时候,不能搪塞了事。

我目前所在的团队正在做一个听起来挺无聊的需求:给产品中的某功能换名字。我们的产品旨在帮助企业员工提高心理健康水平,在必要时进行干涉并提供援助。这个产品已经上线两个月,收到了不错的用户/客户反馈,但是从GA收集到的数据来看,发现我们当初产品设计阶段收到正面反馈的一个功能使用率并不理想。团队经过用户研究发现,从某种程度上看,是这个功能的名字出了问题。因为用户大多常常处在焦虑状态,这个叫“Goal”的小功能让人觉得压力山大,commitment很重以至于overwhelming,结果干脆不用;我们将在下次发布中,把“goal”换成“pathway”,让人觉得这是压力生活下的一条绿幽小径而非任务/目标。

Stay hungry, stay foolish

用户研究和验证的方法千千万,我不在这里一一列举。Stay hungry, stay foolish这句用烂了的话,恐怕是我能找到的最契合“BA怎么做用户研究和验证”的原则。面对客户的需求,多问一个为什么;面对用户的答案,多想一个为什么;能最大程度地避免“想当然”,或许就能最大程度地做好“用户研究和验证”

我们常常形容需求是冰川,露出海面的只是冰川一角。写到这里,我忽然想起去年夏天我在某客户的合作工厂做用户测试,工人们因为厂房过于炎热光着膀子也不带安全帽,我趁他们休息间隙想要和他们聊一聊,我走过去蹲在抽烟的人们旁边想要加入他们,但几乎于此同时,大家都站起来离开了。想要融化冰川,或许不只是挖掘那么简单。


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

Share

Serverless的微服务持续交付案例

本文是GitChat《Serverless 微服务的持续交付》部分内容已做修改。文章聊天实录请见:“顾宇:Serverless 微服务的持续交付解析

Serverless 风格微服务的持续交付(上):架构案例”中,我们介绍了一个无服务器风格的微服务的架构案例。这个案例中混合了各种风格的微服务。

架构图如下:

在这个架构中,我们采用了前后端分离的技术。我们把 HTML,JS, CSS 等静态内容部署在 S3 上,并通过 CloudFront 作为 CDN 构成了整个架构的前端部分。我们把 Amazon API Gateway 作为后端的整体接口连接后端的各种风格的微服务,无论是运行在 Lambda 上的函数,还是运行在 EC2 上的 Java 微服务,他们整体构成了这个应用的后端部分。

从这个架构图上我们可以明显的看到 前端(Frontend)和后端(Backend)的区分。

持续部署流水线的设计和实现

任何 DevOps 部署流水线都可以分为三个阶段:待测试,待发布,已发布

由于我们的架构是前后端分离的,因此我们为前端和后端分别构造了两条流水线,使得前后端开发可以独立。如下图所示:

(整体流水线)

在这种情况下,前端团队和后端团队是两个不同的团队,可以独立开发和部署,但在发布的时候则有些不同。由于用户是最后感知功能变化的。因此,为了避免界面报错找不到接口,在新增功能的场景下,后端先发布,前端后发布。在删除功能的场景下,前端先发布,后端后发布。

我们采用 Jenkins 构建我们的流水线,Jenkins 中已经含有足够的 AWS 插件可以帮助我们完成整个端到端的持续交付流水线。

前端流水线

前端持续交付流水线如下所示:

前端流水线的各步骤过程如下:

  1. 我们采用 BDD/ATDD 的方式进行前端开发。用 NightWatch.JS 框架做 端到端的测试,mochachai 用于做某些逻辑的验证。
  2. 我们采用单代码库主干(develop 分支)进行开发,用 master 分支作为生产环境的部署。生产环境的发布则是通过 Pull Request 合并的。在合并前,我们会合并提交。
  3. 前端采用 Webpack 进行构建,形成前端的交付产物。在构建之前,先进行一次全局测试。
  4. 由于 S3 不光可以作为对象存储服务,也可以作为一个高可用、高性能而且成本低廉的静态 Web 服务器。所以我们的前端静态内容存储在 S3 上。每一次部署都会在 S3 上以 build 号形成一个新的目录,然后把 Webpack 构建出来的文件存储进去。
  5. 我们采用 Cloudfront 作为 CDN,这样可以和 S3 相互集成。只需要把 S3 作为 CDN 的源,在发布时修改对应发布的目录就可以了。

由于我们做到了前后端分离。因此前端的数据和业务请求会通过 Ajax 的方式请求后端的 Rest API,而这个 Rest API 是由 Amazon API Gateway 通过 Swagger 配置生成的。前端只需要知道 这个 API Gateway,而无需知道API Gateway 的对应实现。

后端流水线

后端持续交付流水线如下所示:

后端流水线的各步骤过程如下:

  1. 我们采用“消费者驱动的契约测试”进行开发,先根据前端的 API 调用构建出相应的 Swagger API 规范文件和示例数据。然后,把这个规范上传至 AWS API Gateway,AWS API Gateway 会根据这个文件生成对应的 REST API。前端的小伙伴就可以依据这个进行开发了。
  2. 之后我们再根据数据的规范和要求编写后端的 Lambda 函数。我们采用 NodeJS 作为 Lambda 函数的开发语言。并采用 Jest 作为 Lambda 的 TDD 测试框架。
  3. 和前端一样,对于后端我们也采用单代码库主干(develop 分支)进行开发,用 master 分支作为生产环境的部署。
  4. 由于 AWS Lambda 函数需要打包到 S3 上才能进行部署,所以我们先把对应的构建产物存储在 S3 上,然后再部署 Lambda 函数。
  5. 我们采用版本化 Lambda 部署,部署后 Lambda 函数不会覆盖已有的函数,而是生成新版本的函数。然后通过别名(Alias)区分不同前端所对应的函数版本。默认的 $LATEST,表示最新部署的函数。此外我们还创建了 Prod,PreProd, uat 三个别名,用于区分不同的环境。这三个别名分别指向函数某一个发布版本。例如:函数 func 我部署了4次,那么 func 就有 4个版本(从1开始)。然后,函数 func 的 $LATEST 别名指向 4 版本。别名 PreProd 和 UAT 指向 3 版本,别名 Prod 在 2 版本。
  6. 技术而 API 的部署则是修改 API Gateway 的配置,使其绑定到对应版本的函数上去。由于 API Gateway 支持多阶段(Stage)的配置,我们可以采用和别名匹配的阶段绑定不同的函数。
  7. 完成了 API Gateway 和 Lamdba 的绑定之后,还需要进行一轮端到端的测试以保证 API 输入输出正确。
  8. 测试完毕后,再修改 API Gateway 的生产环境配置就可以了。

部署的效果如下所示:

(API Gateway + Lambda 配置)

无服务器微服务的持续交付新挑战

在实现以上的持续交付流水线的时候,我们踩了很多坑。但经过我们的反思,我们发现是云计算颠覆了我们很多的认识,当云计算把某些成本降低到趋近于 0 时。我们发现了以下几个新的挑战:

  1. 如果你要 Stub,有可能你走错了路。
  2. 测试金字塔的倒置。
  3. 你不再需要多个运行环境,你需要一个多阶段的生产环境 (Multi-Stage Production)。
  4. 函数的管理和 Nanoservice 反模式。

Stub ?别逗了

很多开发者最初都想在本地建立一套开发环境。由于 AWS 多半是通过 API 或者 CloudFormation 操作,因此开发者在本地开发的时候对于AWS 的外部依赖进行打桩(Stub) 进行测试,例如集成 DynamoDB(一种 NoSQL 数据库),当然你也可以运行本地版的 DynamoDB,但组织自动化测试的额外代价极高。然而随着微服务和函数规模的增加,这种管理打桩和构造打桩的虚拟云资源的代价会越来越大,但收效却没有提升。另一方面,往往需要修改几行代码立即生效的事情,却要执行很长时间的测试和部署流程,这个性价比并不是很高。

这时我们意识到一件事:如果某一个环节代价过大而价值不大,你就需要思考一下这个环节存在的必要性。

由于 AWS 提供了很好的配置隔离机制,于是为了得到更快速的反馈,我们放弃了 Stub 或构建本地 DynamoDB,而是直接部署在 AWS 上进行集成测试。只在本地执行单元测试,由于单元测试是 NodeJS 的函数,所以非常好测试。

另外一方面,我们发现了一个有趣的事实,那就是:

测试金字塔的倒置

由于我们采用 ATDD 进行开发,然后不断向下进行分解。在统计最后的测试代码和测试工作量的的时候,我们有了很有趣的发现:

  • End-2-End (UI)的测试代码占30%左右,占用了开发人员 30% 的时间(以小时作为单位)开发和测试。
  • 集成测试(函数、服务和 API Gateway 的集成)代码占 45%左右,占用了开发人员60% 的时间(以小时作为单位)开发和测试。
  • 单元测试的测试代码占 25%左右,占用了10%左右的时间开发和测试。

一开始我们以为我们走入了“蛋筒冰激凌反模式”或者“纸杯蛋糕反模式”但实际上:

  1. 我们并没有太多的手动测试,绝大部分自动化。除了验证手机端的部署以外,几乎没有手工测试工作量。
  2. 我们的自动化测试都是必要的,且没有重复。
  3. 我们的单元测试足够,且不需要增加单元测试。

但为什么会造成这样的结果呢,经过我们分析。是由于 AWS 供了很多功能组件,而这些组件你无需在单元测试中验证(减少了很多 Stub 或者 Mock),只有通过集成测试的方式才能进行验证。因此,Serverless 基础设施大大降低了单元测试的投入,但把这些不同的组件组合起来则劳时费力 。如果你有多套不一致的环境,那你的持续交付流水线配置则是很困难的。因此我们意识到:

你不再需要多个运行环境,你只需要一个多阶段的生产环境 (Multi-Stage Production)

通常情况下,我们会有多个运行环境,分别面对不同的人群:

  1. 面向开发者的本地开发环境
  2. 面向测试者的集成环境或测试环境(Test,QA 或 SIT)
  3. 面向业务部门的测试环境(UAT 环境)
  4. 面向最终用户的生产环境(Production 环境)

然而多个环境带来的最大问题是环境基础配置的不一致性。加之应用部署的不一致性。带来了很多不可重现问题。在 DevOps 运动,特别是基础设施即代码实践的推广下,这一问题得到了暂时的缓解。然而无服务器架构则把基础设施即代码推向了极致:只要能做到配置隔离和部署权限隔离,资源也可以做到同样的隔离效果。

我们通过 DNS 配置指向了同一个的 API Gateway,这个 API Gateway 有着不同的 Stage:我们只有开发(Dev)和生产(Prod)两套配置,只需修改配置以及对应 API 所指向的函数版本就可完成部署和发布。

然而,多个函数的多版本管理增加了操作复杂性和配置性,使得整个持续交付流水线多了很多认为操作导致持续交付并不高效。于是我们在思考:

对函数的管理和“ Nanoservices 反模式 ”

根据微服务的定义,AWS API Gateway 和 Lambda 的组合确实满足 微服务的特征,这看起来很美好。就像下图一样:

但当Lambda 函数多了,管理众多的函数的发布就成为了很高的一件事。而且, 可能会变成“Nanoservice 反模式”:

Nanoservice is an antipattern where a service is too fine-grained. A nanoservice is a service whose overhead (communications, maintenance, and so on) outweighs its utility.

如何把握微服务的粒度和函数的数量,就变成了一个新的问题。而 Serverless Framework ,就是解决这样的问题的。它认为微服务是由一个多个函数和相关的资源所组成。因此,才满足了微服务可独立部署可独立服务的属性。它把微服务当做一个用于管理 Lambda 的单元。所有的 Lambda 要按照微服务的要求来组织。Serverless Framework 包含了三个部分:

  1. 一个 CLI 工具,用于创建和部署微服务。
  2. 一个配置文件,用于管理和配置 AWS 微服务所需要的所有资源。
  3. 一套函数模板,用于让你快速启动微服务的开发。

此外,这个工具由 AWS 自身推广,所以兼容性很好。但是,我们得到了 Serverless 的众多好处,却难以摆脱对 AWS 的依赖。因为 AWS 的这一套架构是和别的云平台不兼容的。

所以,这就又是一个“自由的代价”的问题。

CloudNative 的持续交付

在实施 Serverless 的微服务期间,发生了一件我认为十分有意义的事情。我们客户想增加一个很小的需求。我和两个客户方的开发人员,客户的开发经理,以及客户业务部门的两个人要实现一个需求。当时我们 6 个人在会议室里面讨论了两个小时。讨论两个小时之后我们不光和业务部门定下来了需求(这点多么不容易),与此同时我们的前后端代码已经写完了,而且发布到了生产环境并通过了业务部门的测试。由于客户内部流程的关系,我们仅需要一个生产环境发布的批准,就可以完成新需求的对外发布!

在这个过程中,由于我们没有太多的环境要准备,并且和业务部门共同制定了验收标准并完成了自动化测试的编写。这全得益于 Serverless 相关技术带来的便利性。

我相信在未来的环境,如果这个架构,如果在线 IDE 技术成熟的话(由于 Lambda 控制了代码的规模,因此在线 IDE 足够),那我们可以大量缩短我们需求确定之后到我功能上线的整体时间。

通过以上的经历,我发现了 CloudNative 持续交付的几个重点:

  1. 优先采用 SaaS 化的服务而不是自己搭建持续交付流水线。
  2. 开发是离不开基础设施配置工作的。
  3. 状态和过程分离,把状态通过版本化的方式保存到配置管理工具中。

而在这种环境下,Ops工作就只剩下三件事:

  1. 设计整体的架构,除了基础设施的架构以外,还要关注应用架构。以及优先采用的 SaaS 服务解决问题。
  2. 严格管理配置和权限并构建一个快速交付的持续交付流程。
  3. 监控生产环境。

剩下的事情,就全部交给云平台去做。


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

Share

亲历者说:敏捷?我被洗脑了吗?

几年之前我还是个野生程序员的时候,对“敏捷”这个词是有些抗拒的。那时候,要么是没有想法、懒得去理会,要么就是主观上拒绝:

肯定又是些无所事事的人弄出来的无聊概念,帮他们自己刷存在感的东西!

敏捷,就是那些咨询公司弄出来给别人洗脑的嘛,那些理念太空,根本无法落地!

那些一大堆概念都是些什么鬼?条条框框太多了,运作起来太麻烦了!

不用敏捷,我们现在不也挺好的吗?敏捷跟我有什么关系?

但后来我却选择加入了 ThoughtWorks,这个传说中的敏捷大本营,一方面因为很多出名的书都是 ThoughtWorks 的人出的,另一方面也想亲入虎穴一探究竟。而如今,历经敏捷项目的洗礼,我已经成为专职的一线咨询师,为众多大型企业提供敏捷转型过程中的技术指导。

他们

在一些朋友看来,我自从换了工作,就开始在群里转发一些敏捷相关的文章,发表一些感言。在转发这些内容的时候,我经常用到的叙事口吻是“他们”。

他们的代码真的写了好多测试。

有时候要开一整天的会,我真不知道他们是怎么撑下来的!

感觉跟着他们一起做测试驱动开发好像没那么难。

这段时间里,我让自己成为一个“警惕的观察者”。不管是主观上的警觉,还是故意在外人面前将自己打造成这样的一个形象。深怕在我还没有觉察到的时候就已经被敏捷洗脑了;同时也希望在曾经的好友面前以尽量理性、中立和客观(理中客)的形象示人:不过,这不妨碍在他们看来,我已经被洗脑了。

后来我了解到,这如同学习新知识过程“守破离”中“守”的阶段。“守”的过程既是获取新认知的过程,也是与过去的认知做比较和更新的过程。观察现象——对比质疑——私下学习——拨开疑云,大体就是这样的不段重复,在不断了解新实践的过程中,也同步去认识它、理解它。

渐渐地,一系列疑问得以解答,使得最终我接纳了敏捷开发思想,并认为它是适用于现代开发团队中的工作方法。

疑问

在过去我呆过的团队中,一直有两个无法解答的问题。那时作为技术经理,我经常被别人问到的问题,也是我自己无法用经验回答的问题。

  • 做完这个功能,你估计需要多少时间?
  • 为什么大家在办公室显得很安静、气氛有点压抑?

在成功学的洗脑课程中,有一句被强调最多的话:“失败一定有原因,而成功一定有方法!”那么,我们过去回答不了的上面这些问题,以及由它们导致的管理上的难题,其根本原因又是什么呢?获得管理上成功的方法又是什么呢?我带着这两个问题离开了之前深度参与的创业项目。与朋友分享了要探索新征程的想法之后,他真诚地邀请我加入他的创意,并希望由我来带领团队一起续写新的故事。我猛然间发现,其实虽然之前在团队里担任所谓技术经理的职位,但我真正给团队带来的帮助似乎更多的只是一个有经验的工程师给新手的指导。那时候,第三个疑问产生了:

  • 如何去做好一个团队带头人?应该安排团队成员每天做什么?

这些疑问不得到解答,我就如同掉下井底的青蛙,虽然能听见外面世界的声音,却只能看到井口大小的世界。

答疑

加入新团队后不久,这些疑问就完全得到了解答。第一个要实现的需求就是一个“明星”功能,集成第三方系统的调查问卷。团队很快组织了需求计划会议,并细致地过了一遍第一期要完成的目标,实现这个目标要包含的业务范围,而具体又包含哪些步骤(用户故事)。

  • 目标:发出问卷链接,并将数据收回来。
  • 范围:选取模板、发送链接、收回数据、发送提醒邮件
  • 步骤:
    1.  管理员在外部系统中创建好模板(不需要开发)
    
    1. 用户可在 XX 页面中使用选项来选择问卷模板(系统自动将外部系统中的模板名字同步到本地系统)
    2. 用户可在 YY 页面中使用链接发送调查表单,客户收到包含链接的邮件
    3. 系统自动将外部系统中收到的数据同步到本地系统中以供使用
    4. 如果没收到提交数据,系统自动在7天后自动发出提醒邮件,客户再收到一封包含链接的邮件

接着开发人员和测试人员对还不够详尽的细节提出问题,讨论获得一致,一起对各个步骤大致估计所需时间。每个用户故事并不确定由谁来做,而是大家一起就其中的细节进行讨论,并就所需时间形成一致:有的人说需要 3 天,有的人觉得 2 天就够了。他们会叙述自己的想法,并最终达成共识。

这项活动,以及之后的迭代过程中,基于这个会议的开发过程解答了我第一个疑问。

他们有一个角色叫 BA,会写一个个的用户故事来描述需求,一两天就可以完成一个故事。明确的前提条件和验收标准(从哪里开始做,做到哪里为止),让开发工作变得有节奏感,需求不清楚的时候随时就这个需求的范围进行讨论。

相比于拿别的产品做个演示,甩一句“就照这个做”,然后就天天催进度、做出来之后又说不对劲的产品经理,有一个专门负责业务、随时可以叫过来讨论的 BA 让开发人员感到倍感轻松。

江湖上传言说敏捷不需要文档,原来是谬误。敏捷并没有说不需要文档,只是说认为团队成员之间的沟通协作比详尽的文档更重要。所以,用户故事仍然是会包含必要的描述内容的。要写清楚为什么要做这项功能,以及验收标准等。

团队一起估计时间的过程,不光可以消除特定人估计时的无助感,更重要的是它让所有人都了解用户故事的细节,在后续开发中谁都可以参与开发。

相对较小的用户故事,估计起来要比一整个功能(比如对整个调查问卷功能进行估计)估计起来靠谱得多。即使有特定的用户故事估计不准确,其影响范围也是可控的。

把所有故事的估计时间相加,即为整个功能所需要花费的时间。

估计只是帮助做计划的一种方法,在后续开发过程中,如果发现比当初估计的要复杂,或者简单,需要与 BA、PM 等角色一起更新这个估计值,从而帮助团队及时完善一开始制定的迭代计划(如果必要,可以加入一些,或者减去一些,或者修改一些)。

这样,我发现开发团队的时间原来是需要管理的,而管理时间这件事其实也需要花些心思才能做好。这时候,如果你问我某项功能需要多久做好?我会告诉你,让我来拆分一下功能,粗略估计就成为了可能。

而后面的其他疑问也很快得到了解答。关于团队气氛,如果一个团队里每个成员都在闷头做自己的工作,独自面对自己的交付压力和技术挑战,成员之间互相帮不上忙,他们的气氛一定不会太好。而如果所有人通力配合工作在相同的功能上,一起理解消化业务,一起解决技术问题,共同做技术决策,并分担解决缺陷(BUG)的责任和压力,那么团队的气氛怎么会不好呢?

最后一个问题,关于团队。

团队里大家的角色是如何分配的,规模又应该多大?团队之间应该如何配合?这就不难回答了。典型的业务功能团队,以及后来出现的微服务团队,都很好的诠释了团队结构和规模问题。有一个论述产品设计和组织结构关系的康威定律,值得我们深入思考。团队带头人?我突然反应过来,一定要有这个角色么?如果大家都能很好地运作了,那其实这个所谓带头人的作用是很淡化的,这也就是所谓的自组织团队了。如果一定要一个带头人,那他的职责一定是确保这样一种自组织的机制在团队中持续地运作下去。

所以,我被洗脑了吗?

也许你可以这样认为。

作者我现在是接受了敏捷思想的,其中还有一些工具和方法,我还在持续学习过程中。不过,“洗脑”这个词本身其实具有一定的预设立场,它是那些质疑者的说法。

那么,重新回到问题本身。敏捷是什么呢?它会将人们洗脑吗?

敏捷不是什么宗教,它只是一种生产软件的思路,一种倡议。它倡议,通过加强团队成员间的交流协作,尽快交付高质量、有价值的软件,让团队以良好的响应性来拥抱软件的变化。为了符合这种思路,它一般又会有一些典型的实践方式。我们可以说哪些实践是由敏捷方法所推荐的,因此是“敏捷的”;而哪些实践是不推荐的,因此是“不够敏捷的”。但不会说哪种是好的,哪种是不好的。

比如,敏捷的:

  • 自主提交代码,尽早集成
  • 自动化一切,包括环境初始化
  • 代码由团队共享,随时重构和优化

不敏捷的:

  • 逐次代码提交都需要他人审查并批准的管控
  • 手动部署生产环境
  • 不让他人修改自己编写的代码

但这些“不敏捷”的条目,基于团队具体情况,可能实际操作起来更可行,就可以根据目前的阶段去施行,并向着更敏捷的方向去持续改进。类似地还有,敏捷不会说团队一定要开站会,站会一定要在早上开等等……相反,如果要求团队一定要做某件事,其实它与敏捷思想是背道而弛的。我们应该遵循敏捷理念去对实践进行改良,以适应团队实际情况。

事实上,“敏捷”一词来源于英语 Agile,这一英文词汇也类似于中文中的形容词“敏捷”一词,其适应性相当广泛。人们往往用它来形容业务的灵活性,思路的开放性等。因此对于敏捷来说,并不存在什么洗脑不洗脑的说法。它只是一种风格,一种态度。只要你运用这种思路和风格去让团队协作越来越好,开发出来的软件的质量越来越好,那就是敏捷的。敏捷中典型的具体实践方法有 Scrum)、XP 和 Lean 等。此外,近年被广为谈论的 DevOps,也已经成为了敏捷软件方法的典型实践。


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

Share

我们应该怎样使用开源软件

开源是近年来大火的词汇。自2017年7月Facebook的React开源软件被Apache基金会宣布禁止使用、百度也宣布全面停止使用以来,开源软件的合规性使用引发了大家的关注。

我们以React为例,看看开源软件的坑在哪里。

React的开源许可证

React最初的开源许可证为Facebook 在BSD许可证基础上附加了专利防御保护条款,即BSD+Patents license。

解读

原许可证在著作权授权使用(BSD)的基础上添加了防御性专利侵权条款(Patents),写明在以下三种情况下Facebook授予被许可人的专利权将被撤回:

  1. 如果被许可人对Facebook及其子公司、关联公司提出直接或间接的专利诉讼;
  2. 对其他方提起专利诉讼,且该专利诉讼全部或部分起因于Facebook、其子公司或者关联公司的任何软件、技术、产品或服务;
  3. 就React软件相关发起专利诉讼,起诉其他方。

通俗的可以理解为:只要因为你提起专利诉讼,让Facebook成为被告或者第三人,Facebook都可以撤回React的专利授权。

许可证及后续Facebook的答疑中明确专利权在以下情形下不会被撤回:

  1. 被许可人使用React创造了竞争产品;
  2. 被许可人就专利侵权之外的事项起诉Facebook;
  3. Facebook作为专利诉讼(非因BSD+Patents license授权下的软件相关)的原告,被许可人反诉的情形。

另外,Facebook也明确了专利授权的终止并不会导致著作权许可的终止。

质疑漩涡

Apache基金会在2017年7月禁止Apache 产品中使用遵循BSD+Patents License的JAR包。质疑漩涡进一步发酵,社区激烈地质疑Facebook违背了开源的精神。

虽然并没有现成的案例可以支持。然而,引起大家担忧的是从许可证文本约定来看,如果某公司强依赖性使用React,则Facebook可以自由使用该公司的所有专利。因为只要该公司发起对Facebook的专利诉讼,该公司的React的专利授权就会被撤回。

在持续发酵的情况下,Facebook承诺更换许可证,并于9月26日遵守承诺在发布React16时更换为MIT许可证。然而,对Facebook还坚持使用原许可证的开源项目,仍然应该引起关注。总体而言,React许可证的更换不仅是开源社区的一次胜利,更是提高了企业、开发者对许可证重要性的认识、起到了警示作用。

如何正确使用开源软件

1. 关注开源软件使用的合规性

同开源软件的广泛使用相对应,开源许可证的遵守情况却不容乐观。从法律的角度来讲,使用者自引入某开源软件的时刻起,其开源许可证将自动适用。使用者如未履行许可证规定的义务(如加入版权说明),即构成侵权,或者违反契约(合同)的行为,并因此可能造成许可证的撤回并承担相应的赔偿责任。

例如Netfilter核心开发者团队的 Patrick McHardy,以违反GPL许可证为理由,在德国威胁超过80家公司,并谋利约200万欧元。事后Patrick McHardy被定义为“GPL谋利-版权谋利者”。2016年12月16日美国的软件自由法律中心(Software Freedom Law Center)起诉包含三星在内的14家厂商违反GNU许可证。在中国国内,小米公司也因屡次违反开源协议而被社区指责。从以上案例中也可以看出国内外企业对开源许可证的义务、法律责任均认识不足。

综上,未按照开源许可证约定使用开源软件会引发潜在的法律纠纷,或者给企业带来名誉损失。因此,企业在使用开源软件时应建立审查制度。依据开发软件的用途、目的、市场等情况判断是否引入某开源软件。

就软件开发服务提供者而言,应首先关注同客户的合同约定,在合同约定可以使用的前提和范围下,尽到对客户的通知义务或取得客户的书面同意。以避免因为使用开源软件导致的合同违约或者被追偿。

2. 关注开源软件使用的安全性

开源软件由于贡献者的能力不同导致可能存在安全漏洞。因此,开发者在享受开源软件的便利时,应注意漏洞的识别,并采取相应的代码安全审计,并将已披露漏洞及修复方案及时告知客户。

3. 制定开源软件使用政策。

如果公司在业务中大量采用开源软件,则制定并执行开源使用政策就变得尤为重要。根据公司业务的不同,政策可以涵盖公司对开源的态度(是否支持,创建社区还是加入某社区)、哪些应用可以开源,哪些应用可以使用开源软件;哪些许可证类型的开源软件可以使用、审查流程等。从而最大限度的避免公司的知识产权侵权风险。


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

Share

创新,最重要的是信念 | 产品创新读书雷达发布啦!

首先,读书,当然不能保证我们可以做出成功的产品。

不记得在哪里看过说,“读书,其实是为了培养信念”,对于产品创新这件事也是一样。读书,会让我们明白:

  • 有那么多事,值得我们去改变;
  • 原来,我们也能够去改变;
  • 原来有这么些逻辑和方法,可以避免愚蠢的错误;
  • 只要具有钢铁般的意志,终将抵达彼岸。

“我这辈子遇到的来自各行各业的聪明人,没有一个不是每天阅读的——没有,一个都没有。而巴菲特·沃伦读书之多,可能会让你感到吃惊,他是一本长了两条腿的书!”巴菲特合伙人查理·芒格曾这样评价巴菲特。

但我们也不想让大家为读书而焦虑。因此,基于以下的原则,我们筛选出了32本书:

  • 聚焦产品创新主题;
  • Less is More,少就是多;
  • 兼顾格局、视野与实用、落地;
  • 趣味和思想 胜于 全面和细致。

如果你是想尝试产品创新、已经在做产品、或是想在组织里培养更多产品创新者的人,那么下面这份读书雷达或许可以帮到你:

Share