一种可拯救产品与开发关系的良药——“高内聚低耦合”

KUN
13 评论 11706 浏览 245 收藏 11 分钟

需求是一个很玄的东西,总会影响产品经理和开发的关系。为此,本文作者分享了一种可拯救产品与开发关系的良药——“高内聚低耦合”。因为“高内聚低耦合”的产品设计能保证“可复用/可扩展/够灵活/可维护”,从而提升产品迭代效率/增进和开发的感情。

产品经理做功能规划时一定经常遇到这样的问题:

  1. 需求变更或产品设计不合理导致修改成本很高时,产品被开发骂,甚至被打。
  2. 需求评审时,开发会说“不要相信产品经理“/”这里不要听他的,到时候肯定会让我们改” ,信任崩坏。

其实,产品一点也不想改需求。可是业务情况不断在变,导致和开发的关系总是被改需求这件事破坏。

怎么办?

  • 首先,冲突是不可避免的。承认产品和开发中任务目标和思考方式上存在差异,不必太过紧张,在冲突中协作并推进项目是常态
  • 其次,需求总是会改的。与其承诺不改,不如让产品改起来十分顺滑。这就要努力去理解开发的工作特征,在设计产品的时候做个“有脑子的pm”。

今天和大家分享其中非常重要的一点——产品设计中的 *高内聚低耦合* 就是拯救产品开发关系的良药。

什么是高内聚低耦合?

这犀利的措辞一看就是来自开发界的术语。高内聚是说一个功能模块最好仅完成一个独立的子功能并且完成的很好。低耦合是指模块与模块之间尽量独立/联系少/接口简单。

这个原则出现的背景是为了让程序“可复用/可扩展/够灵活/可维护”。干过一阵子产品的人对这几个词应该都不陌生。对于程序设计者来说,这几个词是十分重要的,不亚于产品经理口中的“用户体验”(原则or挡箭牌)。

那么,怎么能让你的需求设计符合以上原则呢?

分3步:

  1. 把一个具体的问题抽象成一类问题;
  2. 根据用户体验流程划分功能模块;
  3. 针对每个功能设计封闭的解决方案。

下面一个一个讲:

1、从对象到类,从具体到抽象,产品经理要尽量解决一类问题而不是一个问题

比如老板说这周要上一个大转盘抽奖的活动,送两部iPhone7拉升一下用户活跃。大转盘几乎时每个产品经理/开发的噩梦,拿到题目立即打开axure开始飙车?no!先把这个具体到活动需求升级到一类问题来考虑:

  • 这次的大转盘送iPhone7,下次送话费怎么改?
  • 大转盘是个抽奖活动,下次老板又看上了砸金蛋怎么改?
  • 这次是奖励新用户的,下次换成会员才可以抽奖怎么改?
  • 大转盘是运营型产品,万一下个月要对接外部合作者引流怎么改?
  • 甚至下次开始做转发集赞送礼品了,怎么改?

你要从“策划一个(抽奖)活动系统”的角度来思考,目标定为解决快速支持运营(抽奖)活动这一类问题;如此得出的方案才有可能是“通用”的,支持比较多的“变种”。

2、绘制用户体验流畅图,按照“单一责任原则”划分功能模块

不同的角色甚至同一角色都可能有不同的任务目标,需要逐一分析。

比如在大转盘类产品中,一个参与用户在活动中的体验流程是:

①用户看到活动页面→②系统判断活动有效性→③用户执行抽奖操作→④系统判断用户是否符合参与条件→⑤系统给出奖励结果→⑥输出结果页面给用户→⑦用户执行领奖操作

  1. 最初应该如何划分事件模块?我的经验是参考生活经验并根据你当前所要处理的任务目标来确定粒度的粗细,比如现在我们在设计一个抽奖的活动系统,我的划分粒度就先到组成这个系统的大模块。如果现在我们开始设计抽奖的前端页面,我们的划分粒度就要拆解到页面的组成部分。
  2. 如何确定模块规划符合高内聚低耦合的标准?一个判断标准是:单一责任原则。简单说就是一个模块只做一件事,只承担一项职责,因为承担的责任越多,它被复用的可能性就越小。如果承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作,于是就会导致开发骂娘——“这个功能改不动”、“这相当于重做一个”

为了方便操作,我个人总结如下图:

左边举例:假设将“④系统判断用户是否符合参与条件→⑤系统给出奖励结果”规划为一个功能模块A,我们将会发现A的输出结果有两种类型,一个类型是用户老王不是注册用户不具备抽奖资格(假设活动要求平台注册用户才能抽奖),另一个类型是老王具备抽奖资格但是没有抽中(假设完全随机抽奖)。在这种情况下,出现两种类型的结果输出,说明该模块的耦合度高了——应该拆成2个模块,一个专门判断用户是否有资格来抽一把,一个专门判断有资格的用户得到哪个奖品。

①用户看到活动页面→②系统判断活动有效性→③用户执行抽奖操作→**A 系统给出奖励结果**→⑥输出结果页面给用户→⑦用户执行领奖操作

右边举例:假设将“⑤系统给出奖励结果”拆成两个模块“A 用户抽中哪个奖品→B 该奖品是否已达最大量”,我们将会发现要得到用户中奖结果一定要模块A和B同时起作用才行,也可以说A和B在承担同一个责任。说明该模块的内聚度低——应该合并成1个模块。

①用户看到活动页面→②系统判断活动有效性→③用户执行抽奖操作→④系统判断用户是否符合参与条件→**A 用户抽中哪个奖品→B 该奖品是否已达最大量(已抽完或每日限量)**→⑥输出结果页面给用户→⑦用户执行领奖操作

3、针对每个功能模块,明确输入和输出,设计完整封闭的解决方案,打造对上下游的黑盒

根据第2部分的用户体验流程,把活动系统划分归类出以下模块:

  1. 活动页面管理:页面创建、编辑、banner图替换、转盘样式切换、活动规则页编辑等;
  2. 活动有效性管理:基础信息配置、活动时间设定、定时上线下线等;
  3. 参与条件管理:配置参与活动的各项条件,比如用户等级、性别、购物满××元等;
  4. 奖池系统:奖品配置、数量限制、概率参数调整等。

我们以“参与条件管理模”块为例:

  • 输入:供判断的一堆参数,较大可能会随业务变化而增减
  • 黑盒:内部工作单元,根据参数输入执行具体的判定
  • 输出:告诉抽奖系统该用户上否有资格参与抽奖,yes/no

如下图:

厘清之后,该功能模块和上下游切割的就比较干净了:仅完成判断用户是否有资格参与抽奖的任务,高内聚。上游对接判断的参数条件,根据业务需求增加入参和对应的判断模块即可,下游只输出是否可以参加有奖的信息,低耦合。

总结

“高内聚低耦合“的产品设计能保证“可复用/可扩展/够灵活/可维护”,从而提升产品迭代效率/增进和开发的感情。

产品经理可参考以下方法规划产品模块:

  1. 从对象到类,从具体到抽象,产品经理出手是要解决一类问题而不是一个问题;
  2. 绘制用户体验流畅图,按照“单一责任原则”划分功能模块;
  3. 对每个功能模块,明确输入和输出,设计完整封闭的解决方案,打造对上下游的功能黑盒。

最后,本人无技术背景,技术出身的pm如果想打我,请不要打脸。

 

作者:kk,前腾讯产品经理,创业中,柚子生活COO。个人公众号:K星异客。

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

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 深入浅出,还有手绘,点个赞

    来自江苏 回复
  2. 耦合度是指模块之间的关联程度,内聚是指模块内部的元素的关联度

    来自上海 回复
  3. 黑盒的输入数据有用户信息和订单信息,可以理解为多个模块输出一种结果,那是否和单一责任制的低内聚互相矛盾呢

    来自上海 回复
  4. 感谢,总算搞明白产品设计该怎么利用这个概念了

    来自上海 回复
  5. 感谢,文章浅显易懂,简单明了,例子也很清晰,不过技术小白最后的解决方式没怎么看懂

    来自上海 回复
  6. 感谢!之前一直弄不懂这个概念!

    来自湖南 回复
  7. 最好的产品经理是全栈型的,懂运营、懂市场、懂开发、懂设计也就是俗称的公司老板!哈哈!

    来自上海 回复
  8. 干货满满,深入浅出,感谢分享。

    来自浙江 回复
  9. 所以其实设计模式对产品而言也是必修课。

    回复
  10. 以后要做一个这种产品

    回复
  11. 开发眼里最好的产品经理自然是有开发思维的产品。总结的很好,在现实中也不难做到。

    回复
  12. 感谢,分析的很好,同为不懂技术的产品一枚!学习了

    回复
    1. 作为一个干了10年开发的老技术,赞同高内聚低耦合的设计原则。系统就应该这样设计啊!软件工程书里写了几十年了!

      回复