产品状态设计,看这一篇就够了

微信扫一扫,分享到朋友圈

产品状态设计,看这一篇就够了

编辑导语:产品状态的设计,听起来彷佛并不难,但是实际上并不简单。这里面有许多注意事项,需要牢记才能在产品状态设计中避免出错。在这篇文章中,作者回顾了一些基础知识,并且总结了设计原则和设计流程,希望能对各位读者有帮助。

在产品设计中,“状态”是非常重要的设计点,它看起来很简单,似乎只要定义好几个词就够了。

但实际上有很多注意要点,稍不留神就会掉坑里的,所以很多同学在梳理的过程中会感觉越理越复杂、越理越混乱。

这一篇我们就来详细聊聊产品状态的设计。

一、基础知识

1. 状态的定义

状态是什么?

状态是对某一对象一个时间段内业务进展的概括性描述。

我们将这个定义分解一下:

  • 某一对象:状态是用来描述业务中一个具体对象的,每个对象的状态是独立的,只属于它自己;
  • 一个时间段:状态表示的是一个时间段,而不是一个时间点,它不是一个瞬时动作;
  • 业务进展:状态说明的是对象在业务中的进展;
  • 概括性描述:状态具有概括性,是对对象的精简描述。

例如下图中淘宝的商品订单状态,描述对象是商品订单,每个状态都会持续一段时间,这些状态说明的是商品订单在流转过程中的进展,每个状态的描述都非常精简,格式也很统一。

图1 商品订单状态示例

2. 状态的三要素

状态是由输入条件、状态描述、终止条件三个要素组成。

图2 状态三要素示例

1)输入条件

输入条件是进入这个状态的触发开关,当条件被满足,就会执行一次状态的迁移,即进入此状态。如上图中,“用户付款成功”后,商品就会进入【待发货】状态,“用户付款成功”就是【待发货】的输入条件。

2)状态内容

即这个状态是什么。

3)终止条件

终止条件是这个状态结束的开关,当条件满足时,此状态就会终止。如上图中的“商家发货”,就是【待发货】状态的终止条件。

上一状态的终止条件,是下一状态的输入条件,例如下图中“商家发货”是【待发货】的终止条件,是下一状态【待收货】的输入条件。

图3 终止条件与输入条件

无论是输入条件还是终止条件,都包含手动和自动两种:

  • 手动:即需要用户手动触发,如“商家发货”,就需要商家手动点击“发货”按钮,或输入发货单号并手动提交成功,系统才可判断商品终止了【待发货】状态,进入【待收货】;
  • 自动:即无需用户手动操作,系统根据已设置好的规则,当规则满足后,自动执行状态迁移。

这两种类型的条件可同时存在,也可只存在其中一种。如商品从【待收货】流转到【待评价】状态,既可手动触发,又有自动触发机制:

  • 手动:用户主动点击“确认收货”按钮;
  • 自动:从状态流转到【待收货】起开始计算,10天后,系统会自动确认收货,状态变更为【待评价】。

我们在设计状态流转时,会尽量减少需要用户手动触发的条件,改为自动触发,但很多时候系统无法做到完全自动,有些环节只能通过用户操作来完成。

然鹅,众所周知,用户都是懒的,用户都是上帝。

我们无法强迫每个用户按照我们的要求去做,只要有需要手动触发的条件,就一定会有用户不主动做,这就会导致后续流程无法继续进行,所以对于状态流转比较重要的节点,我们大多会采用手动为主,自动为辅。

的原则,即预留一定的时间等待用户手动操作,当即将到达这个时间时,给予一定的预警提示,如若用户仍不操作,则在到达时间后由系统自动向更为常见的方向执行。

3. 状态的作用

状态的作用主要有三个。

1)展示进展

向用户展示此对象的当前进展,以缓解用户的焦虑,降低内心的不确定感,从而提升用户体验。

2)便于描述

将对象不同阶段进行归纳,便于日常沟通。

3)统一规则

对于同一角色,一个对象在一个状态中的规则、操作权限是相同的,不应出现状态前半段权限是A,后半段是B的情况,这一点无论是对用户还是开发都是有意义的。

4. 状态流程

将一个对象各个状态按时间线串联起来,得到的就是这个对象的状态流程。

图4 状态流程示例

二、设计原则

1. 完整连贯

一个对象的状态是贯穿这个对象整个生命周期的,前后两个状态是紧密衔接的,中间不应出现任何真空时期。

图5 完整连贯示例

2. 唯一性

唯一性是指一个对象在一个时间点只有一个状态,不会同时存在多种同级状态,这是很多同学在设计时没有意识到的一点,其中有两个场景是大家容易混淆的:

1)父子状态

一个对象有父子状态是比较常见的场景,例如前文提到的【待收货】,是一个比较笼统的父状态,它其实包含了【已揽件】、【运输中】、【派送中】、【待取件】多个子状态。

图6 待收货的子状态

定义父子状态的目的,是因为有时候子状态过多,在向用户展现时不方便,这时就可以将几个相近的子状态归纳为一个父状态,并以父状态展示给用户。

在这类场景中,有的同学可能就会认为这个商品订单在一个时间点同时有两个状态,但实际上商品订单是以子状态来流转的,所以订单的真实状态是子状态,父状态只是套的一层壳。

2)多名称

多名称是另一个容易混淆的场景,因为有的同学会把多个名称误以为多个状态。

买家收到商品后,订单就应该从【待收货】向下一状态转移,这时我们有【已收货】、【待评价】两个名称可以用,内涵也是一样的。在这类场景中,虽然叫法不同,但其实还是同一个状态。

3. 区分视角

虽然一个对象在一个时间点只有一个状态,但不代表只有一个名称。

在实际状态设计中,为了让不同角色的用户更好的理解一个状态的含义,有时即使是同一状态,针对不同角色用户也会使用不同名称。

4. 统一规则

前面提到,定义状态很重要的一个作用是为了统一这个状态下对象的规则,但要想达到这一目的,就得在设计对象状态时遵守这一原则。

5. 粒度适中

很多同学在梳理对象状态时,随着对流程的细化,会发现这些状态越理越细、越理越多,感觉这里可以加个状态,那里也可以加个状态,最后导致这一对象的状态特别多,状态流特别复杂,徒增用户理解和实现成本。

我们在定义对象状态时,在满足前面原则的前提下,应尽量减少引入更多的状态,控制状态粒度。

6. 通俗易懂

状态名称需要精炼的表达出对象当前阶段的核心进展,并容易被大家所理解,如果实在找不到合适的通俗易懂的词,就要在状态旁边做好说明。

7. 与业务流同向

在状态的定义中,我们强调了状态描述的是业务进展,这里包含的另一层意思是状态流程其实是对业务流程的概括,状态流是在业务流程的基础上总结出来的。

所以状态流程与业务流程一定是同向的,即这个对象在业务上如何流转,它的状态就会以同样的方向流转。

三、设计流程

1. 第一步:梳理操作流程

在设计原则2.7中,我介绍了状态流程与业务流程的关系,那我们是不是有了业务流程就能梳理出状态流程呢?

答案当然是否定的,不然我为什么要问呢。

业务流程之所以不能帮助我们梳理出状态流程,是因为业务流程只能帮我们提炼出状态三要素中的“状态描述”,无法帮助我们精准的确定另外两个要素——“输入条件”和“终止条件”。

大家都知道,在代码实现中,状态要想在系统中流转,需要精确的指令才能进行下一步,这些指令就是状态的“输入条件”和“终止条件”,而业务流程的粒度显然无法满足系统对“精确”的要求,例如商品流转的业务流程是:

图7 业务流程示例

在这个流程中,系统无法知道什么算“商家发货”、什么叫“物流配送”。

所以业务流程无法直接指导系统进行状态流转,这时就需要我们梳理出对象在系统中的操作流程,通过系统中明确的操作或业务规则来向系统发出精准指令。

图8 操作流程示例(过程做了大量简化)

在这个操作流程中,对于系统自动处理的部分,可以通过增加一个名为“系统”的泳道,来体现系统自动完成的操作。

虽然状态流程是在操作流程的基础上梳理的,但操作流程却是在业务流程的基础上细化出来的,所以业务流程也是很重要的(要充分理解这一步,需要先理解业务流程和操作流程的含义和区别,不过这要扯很久,也偏题了,所以关于各种流程的介绍我们择日再聊)。

2. 第二步:归纳状态

在梳理的操作流程基础上,我们再依据前面提到的设计原则,提炼、总结出此对象的各个状态。

同样的,归纳状态时要明确状态的三个要素分别是什么。

3. 第三步:梳理状态流程

有了第二步梳理的各个状态,顺着操作流程的方向,就能得到我们的状态流程了。为了沟通更方便,表达更清晰,状态流程图就是必不可少的,一般的状态流程图有三种表现形式。

1)纯状态流转

即流程图中仅体现状态的流转,不展示其他信息,如下图所示。

图9 纯状态流程图

这种形式很简单、干净,适用于向业务方、上级领导等不需要了解细节的关联方汇报,但对于开发同学来说肯定是不够的,这时就得采用后面两种形式了。

2)与操作流程结合

既然状态流程是在操作流程的基础上梳理的,这就说明这两个流程其实是可以合并处理的。

图10 状态流程与操作流程合并

如上图所示,在状态输入条件后展现状态名称,到下一状态开始前,中间过程均为属于此状态。

这种形式在操作流程较短时比较方便,可以用一张图体现两个流程,但当操作流程较长时,这张图的可读性就比较差了,不同信息间会产生干扰,这时就推荐用第三种方式了。

3)仅体现状态三要素

图11 仅展示状态三要素

如上图所示,这种形式是在上一形式的基础上,去掉中间无关操作,仅保留状态的三要素,这样既可以满足开发同学对触发条件明确的要求,也方便进行讲解汇报。

4. 第四步:整理状态定义表

如果整个状态及流程容易理解,这一步可以省略,但如果定义的状态和相应规则比较复杂,那最好整理一张状态表来说明各个状态的要素、具体含义和相应规则,以便统一各方认识。

表1 状态定义表模板

四、关联对象的状态设计

大多数情况下,能够梳理清楚业务流程和操作流程,清晰准确的定义状态三要素,那状态设计基本就不会有什么问题了。

不过在状态设计中有一类场景会稍微复杂一些——关联对象的状态关系如何处理。

这里的关联对象,是指两个流程进展上相互有影响的对象,例如父子订单,父订单的流程进展受子订单的影响。

举个具体例子,在某个需求管理工具中,假设需求的状态流程为:待处理——开发中——测试中——已完成。

这时小明创建了一个需求,同时在这个需求基础上拆分了两个子需求,那么父子需求的状态关系应该怎么处理呢?这里有几个常见的处理原则。

1. 一个对象仅有一个状态

父子对象虽然在业务上有父子关系,但各自状态是完全独立的,无论是业务角度还是实现角度都是这样,即便两者可能某些状态的命名都一样,但在逻辑上必须是互相独立。

所以虽然状态名称相同,但实际是不同的对象,实质是不同的。

2. 状态关系与对象流程关系相同

既然两个对象在流程上已经相互影响了,那么状态上也会存在一定的逻辑关系,因为状态流程是建立在对象业务(或操作)流程基础上,常见的几类关系有:

1)包含关系

即一个对象在多个状态间流转时,另一对象看到的仍是一个状态。

例如商品消费订单和这个商品的配送订单,就是一对父子关系,消费者看到的消费订单是【配送中】,但配送订单可能会经过【分拣中】、【运输中】等等很多状态,这就是状态的包含关系。

而之所以状态是包含关系,是因为这两个流程是包含关系,商品配送流程可以看作是商品完整流程中的子流程;

2)衔接关系

即一个对象先到某个状态,另一事项才会到某个状态。例如需求要想进入【已完成】状态,需要子任务进入【已完成】,父任务才允许【已完成】。

3)完全同步

即两个对象的状态是同步的,一个对象随另一对象状态变更而变更。

那有的同学会问了,在很多需求管理工具中,虽然父子需求存在父子关系,但为什么他们的状态是完全独立,相互之间不影响呢?

这其实也是体现了这一原则,因为在这些工具的定义中,父子需求的流程上相互没有影响,所以虽然他们存在逻辑关系,但相互间状态不影响。

到这里,关于产品状态的设计就介绍完了,如果各位读者朋友觉得写得还有点用,记得加我微信一起交流哦~~

作者:周翔;公众号:周翔Fly;个人微信:zhouxiangxgg

本文由 @周翔 原创发布于人人都是产品经理。未经许可,禁止转载。

题图来自 Unsplash,基于CC0协议。

微信扫一扫,分享到朋友圈

产品状态设计,看这一篇就够了

Python 字典的items()方法和iteritems()方法有什么不同?【面试题详解】

上一篇

《漫威蜘蛛侠:迈尔斯》结尾彩蛋暗示新作强敌回归

下一篇

你也可能喜欢

产品状态设计,看这一篇就够了

长按储存图像,分享给朋友