用户故事图谱和用户画像

产品愿景

产品愿景(Product Vision)是对未来产品切实可行的构想,建议用一句宣传语来简明地向所有人传递产品愿景。
例如:“针对中型公司的市场和销售部门,CRM-Innovator是一款基于网页服务的产品,提供销售跟踪、商机发现、销售支持等功能以改善客户关系,不同于其他产品,我们产品具有巨大的成本优势。”

用户画像

用户画像(Persona)是真实用户的虚拟代表,建立在一系列真实的市场数据和用户调用数据之上的目标用户模型。建立persona的目的是为了让PO与团队成员在产品设计的过程中能够抛开个人喜好,将焦点关注在目标用户的动机和行为上进行产品设计。PO为具体和特定的人物做产品设计要远远优于为脑中虚构的东西做设计,也更来得容易。有了共同的认知基础,PO和团队在实现产品的时候也更容易对优先级和实现手段达成一致。可以参考书籍《创建定性用户画像》。

继续阅读 More

深入理解代码评审

代码评审(Code Review,以下简称CR)是指通过阅读代码来检查源代码与编码标准的符合性以及代码质量的活动。其目的是帮助提高代码质量,尽早发现由于编码习惯而造成的缺陷,重新梳理思路,最重要的是促进团队沟通共享,共同识别优秀的习惯和模式,把代码评审活动看做一种 学习活动而非批判活动。

内容

  • 编码风格、文档与注释
  • 代码结构
  • 工具框架的使用
  • 功能和业务逻辑、异常处理
  • 安全性、性能
  • 可测性
  • 工具扫描出的违规项和编译器警告

形式

继续阅读 More

TDD测试驱动开发

定义

在编写任何产品代码之前,先写一个测试来表达期望的行为,此时测试应当会失败,因为功能还没有实现。然后编写实现来使测试通过。换句话说,“只为修复失败的测试而编写代码!”
TDD要求测试可以完全地自动化运行,通常会借助单元测试作为基础。

继续阅读 More

单元测试

单元测试(Unit Testing简称UT)是最微小规模的测试;测试粒度在某个类、函数或代码块。典型地由程序员而非测试员来做。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

在Java语言环境下,推荐采用JUnit,也可以和Eclipse集成或单独运行。

语言环境 推荐工具
Java/Android JUnit
C# NUnit
iOS XCTest
Javascript Jasmine

下文以Java的单元测试框架JUnit4和Eclipse为例。

继续阅读 More

重构

为什么要重构?

好的软件除了满足功能需求之外,还应从长期维护的角度来考虑可读性、可扩展性等。没有明显问题,不代表明显没有问题。
然而,随着时间的推移,任何原本设计良好的代码都必然会逐渐腐坏,产生各种代码坏味道,变得难以理解,难以维护,缺陷频出。
随着代码质量下降,问题越来越多,程序员压力也越来越大,而士气也会受到影响,甚至原本的设计队伍都不在了。因而当需要修改bug或添加新需求时,人们更倾向于采用快速的打补丁方式来维护本已不堪的代码,致使代码质量进一步下降,从而造成更多的代码坏味道(Code Smell),形成恶性循环。
采用重构以后,可以有助于改善软件设计,使软件更加容易理解,发现潜在缺陷,从而使未来的编码更加快速。

什么是重构?

重构是指在保持程序的全部功能的基础上重新组织代码结构,以更好地适应将来的变化。重构的类型有很多,如更改类名,改变方法名,或者提取代码到方法中。每一次重构,都要执行一系列的步骤,这些步骤要保证代码和原代码相一致。

继续阅读 More

持续集成

缘起

根据破窗效应,软件中的bug越多,就越难将这些累积在一起的bug去除掉。
提高质量的关键是内建质量,根本不让bug产生,那么就需要将bug扼杀在摇篮里,趁着问题和思路还在你脑子里的时候就解决掉问题。

定义

持续集成(Continuous Integration,以下简称CI)是一种软件开发工程实践,可以让团队持续地收到反馈并进行改进,不必等到开发周期后期才寻找和修复缺陷。持续集成倡导团队开发成员必须频密地集成他们的工作,甚至每天都可能发生多次集成。而每次的集成都是通过自动化的构建来验证,包括自动编译、发布和测试,从而尽快地发现集成错误,让团队能够更快的开发出可工作的软件。

继续阅读 More

全球敏捷之旅2015天津站

全球敏捷之旅2015天津站现场视频。欢迎关注天津软件沙龙、天津谷歌开发者社区。感谢VTC视觉思维提供的现场图像记录。
感谢以下赞助商:优普丰Uperform、Odd-e之AHA大会、安迈无限Unlimax、清华大学出版社、图灵出版社、电子工业出版社、麦思博、天津i2社。

Spotify敏捷工程文化系列视频之中文字幕版

知名音乐网站Spotify的敏捷组织设计与工程文化近两年为人称道,其敏捷教练Henrik Kniberg发布的2段视频功不可没。为了让国内同胞能更好地理解视频的内容,我们成立了一个以Scrum方式工作的字幕翻译小组,将其翻译成中文,他们是:

  • Bill Li, CST, 来自上海优普丰
  • Jacky Shen, CTC/CSD, 来自上海优普丰
  • Roger Chou, CSP/PgMP, 来自台湾长宏

点击下方按钮,可以看到视频




关于这两段视频的解说,请看之前的两篇文章:

视频原帖

  1. https://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/
  2. https://labs.spotify.com/2014/09/20/spotify-engineering-culture-part-2/

强制Gradle/Maven刷新缓存并重新从Nexus下载依赖jar包

最近需要搭建一个Nexus私服,完全不能连接外网的那种,各种Jar包都是手动拷过来的,碰到需要gradle和maven强制重新下载依赖的问题。

问题

第一次上传某个jar包(比如junit-4.12.jar)到Nexus上,然后调用gradle build可以正确下载到依赖包。但如果手动删掉了本地缓存的jar包(在~/.gradle下),这时从Nexus的下载过程中断,或者Nexus上暂时不存在这个jar包,那么即使Nexus恢复了正常下载,下次执行gradle build时就一直提示不能够找到jar包。

FAILURE: Build failed with an exception.

- What went wrong:
Could not resolve all dependencies for configuration ':testCompile'.
> Could not find junit:junit:4.12.
  Searched in the following locations:
      http://localhost:8081/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom
      http://localhost:8081/nexus/content/groups/public/junit/junit/4.12/junit-4.12.jar
  Required by:
      org.codehaus.sonar:example-java-maven:1.0-SNAPSHOT

解决方案

回到自己的工作目录下,带参数执行gradle强制刷新~/.gradle下的文件缓存

1
gradle build --refresh-dependencies

继续阅读 More

使用Groovy语言替代JUnit为Java程序编写单元测试

(本文改编自 @申导 翻译的《有效的单元测试》,如果对本文感兴趣,请支持正版书籍。)

编程是用计算机可理解的语言来表达你的想法和意图。对于Java程序员来说就是编写一种可以由Java编译器编译为可以运行在JVM上的字节码的代码。不止一种编程语言可以编写能运行在JVM上的代码,不过每种JVM语言都具有其独特的语法和感觉,但有一点是相同的:关于在JVM创建应用程序这件事上,她们都号称比Java更加简洁和更具表达力。

另类JVM语言

另类JVM语言的历史可追溯到15年前,那时Jim Hugunin在编写Jython,即一种JVM上的Python语言实现。尽管Jython难以获得发展的动力,但它启发了后来许多JVM语言的出现。

受到Jython的启发,2003年Groovy语言开始在JVM上登场,有着精简语法的Groovy承诺与Java代码之间流畅的互操作性和极高简洁性,使之成为JVM上编写脚本的重要选择。其他运行在JVM平台上的语言还包括Scala, JRuby, Clojure等,以及Java本身。

概括来说,各种另类JVM语言的一些潜在优势在于:

  • 更少的样板代码语法可以去芜存菁
  • 更多的文本(literal)数据结构
  • 针对标准类型的额外方法
  • 更多强大的语法结构

继续阅读 More