<audio id="audio" title="课前加餐 | 电商系统是如何设计的？" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/70/1d/7077b3844c3a4b9518a26dd49428fa1d.mp3"></audio>

你好，我是李玥。

在这个系列课程中，我们会讲电商这个行业在多年系统建设和运维过程中，总结出来的使用分布式存储系统的一些最佳实践。也会以电商系统作为例子来讲解存储相关的技术知识和问题。这都需要你对电商的业务逻辑、系统架构、核心业务流程有一个基本的认知。

虽然说，电商这个业务和你的生活息息相关，你可能对电商多少有一些了解，但是，即使是一个最小化的电商系统，它仍然非常复杂。所以，我们先花一节课的时间，一起以一个创业公司的CTO的视角，设计一个最小化的电商系统，在这个过程中帮你理清楚电商系统的架构。

这样，我们在学习后续课程的时候，就不再解释电商的业务和系统了，直接来讲具体的技术问题。

我们的故事从一个电话开始。某一天，一个曾经认识但并不太熟悉的老板突然来了一个电话：

“我有一个改变世界的想法，就差一个程序员了！你来吧！”

新公司很快就成立了，你成了新公司的CTO。关于要如何改变世界，目前唯一能确定的是，老板要做一个电商系统。具体做成什么样，还不清楚。你需要和老板讨论需求。

你：“咱们要做的业务模式是C2C、B2C还是B2B呢？”

老板：“什么B？什么C？我不懂你们那些技术的东西。”

你：“这么说吧，你要山寨，啊不对，做一个某宝网，还是某东网，还是某848网呢？”

老板：“不都是一样的么？有什么区别？你赶紧做一个出来我看看不就知道了？！”

有没有感觉似曾相识？作为研发谁没碰到过几个啥也不懂的需求方不是？那这种情况下，你怎么办呢？

**在需求还不太明确的情况下，比较可行的方式就是，先把那些不太会变化的核心系统搭建出来，尽量简单地实现出一个最小化的系统，然后再逐步迭代完善。**

## 电商系统的核心流程是什么样的？

接下来我带你一起来设计这个电商的核心系统。

遵照软件工程的一般规律，我们先从需求阶段开始。如何来做需求分析？理想情况下，应该由系统分析师或者是产品经理来承担这个任务。但现实很骨感，绝大多数情况下，你得到的所谓的“需求”，就是一两句话。需求分析的工作实际上就落在了开发者身上。

很多项目交付以后，还要改来改去，用户不满意，开发者很痛苦，其实就是缺失了需求分析这个步骤。所以，为了自己，每一个开发者都应该掌握一点需求分析的方法。

开发者怎么来做需求分析？这里面我们不讲那些做需求分析的方法和理论，只告诉你最重要、最关键的一个点。

不要一上来就设计功能，而是先要回答下面这两个问题：

1. 这个系统（或者是功能）是给哪些人用的？
1. 这些人使用这个系统来解决什么问题？

这两个问题的答案，我把它们称为业务需求。在我们将要设计的这个电商系统中，它的业务需求是什么？电商的业务，每个人都熟悉，很容易回答这两个问题。

第一个问题，电商系统给哪些人用？

首先得有买东西的人，我们叫“用户”，还得有卖东西的人？我们叫“运营人员”。还有什么人会用这个系统？老板啊！你记住，你在设计任何一个系统的时候，千万不要把老板或者是领导给忘了，他们是给你钱的人，他们的意见非常重要！

然后我们一起回答第二个问题：用户、运营和老板，分别用电商系统来干什么？

这个问题也很容易回答，用户用系统来买东西，运营用系统来卖东西，老板需要在系统中看到他赚了多少钱。这两个问题的答案，或者说是业务需求，稍加细化后，可以用下面这个图来清晰的表述：

<img src="https://static001.geekbang.org/resource/image/c7/bc/c75357b43ec89aebd88fbc2a3efcd1bc.jpg" alt="">

这个图在UML（统一建模语言）中称为用例图（Use Case），是需求分析的时候你需要画的第一张图。它回答的就是，业务需求中的那两个关键的问题，这个系统给谁用？他们用这个系统解决什么问题？

一般来说，业务需求和我们要设计的系统关系不大。为什么这么说呢？你可以看一下上面这个图里面的用例，放在传统的商业企业里面，比如一个小杂货铺、一个线下实体商场商店或者一个做电视购物的公司，是不是也是适用的？所以做业务需求的主要目的，是理清楚业务场景是什么样的。

然后我们来分析电商系统的流程。显然，一个电商系统最主要的业务流程，一定是购物这个流程。你应该很容易就能把这个流程分析出来，它的流程图是这样的：

<img src="https://static001.geekbang.org/resource/image/bd/cf/bd778c67b3971e16d3cdbd9fae800dcf.jpg" alt="">

所有的电商几乎都是这样一个流程，我和你一起来看一下这个流程。

流程从用户选购商品开始，用户先从你的App中浏览商品；找到心仪的商品之后，把商品添加到购物车里面；都选好了之后，打开购物车，下一个订单；下单结算之后，就可以支付了；支付成功后，运营人员接下来会给每个已经支付的订单发货；邮寄商品给用户之后，用户确认收货，到这里一个完整的购物流程就结束了。

## 如何根据流程来划分功能模块？

接下来，我们把这个业务流程再细化，看一下电商系统如何来实现这个流程？我把细化之后的流程，绘制成了下面这个时序图（Sequence Diagram）：

<img src="https://static001.geekbang.org/resource/image/f5/ea/f5f3d89c31770591c5d59591a3390eea.jpg" alt="">

我们一起看下这个时序图中的每个步骤。

1. 用户开始浏览商品，需要有一个**商品模块**来支撑，给用户展示商品的介绍、价格等等这些信息。
1. 用户把选好的商品加入购物车，这个步骤，也需要一个**购物车模块**来维护用户购物车中的商品。
1. 用户下单肯定需要一个**订单模块**来创建这个新订单。订单创建好了之后，需要把订单中的商品从购物车中删除掉。
1. 订单创建完成后，需要引导用户付款，也就是发起支付流程，这里需要有一个**支付模块**来实现支付功能，用户成功完成支付之后，需要把订单的状态变更为“已支付”。
1. 之后运营人员就可以发货了，在系统中，发货这个步骤，需要扣减对应商品的库存数量，这个功能需要**库存模块**来实现，发货完成后，还需要把订单状态变更为“已发货”。
1. 最后，用户收货之后，在系统中确认收货，系统把订单状态变更为“已收货”，流程结束。

这个流程涉及到的功能模块有：**商品、购物车、订单、支付和库存，**这几个模块就是一个电商系统中的核心功能模块。

当然，仅仅有这几个模块还是不够的，因为我们只分析了“购物”这个最主要的流程，并没有完全涵盖业务需求中的全部用例，比如：运营人员进货、老板查看报表这些用例还没有覆盖到。

相比购物这个流程，剩下的几个用例和流程都没那么复杂，用同样的方法就可以把其他功能模块分析出来。在这里我们就省略分析过程，直接给出我们电商系统的功能模块划分：

<img src="https://static001.geekbang.org/resource/image/0b/54/0b37cfadd0e181cd9648efc9e9924354.jpg" alt="">

上面这个图，我使用的是UML中的包图(Package Diagram)来表示。整个系统按照功能，划分为十个模块，除了购物流程中涉及到的：商品、订单、购物车、支付、库存五个模块以外，还补充了促销、用户、账户、搜索推荐和报表这几个模块，这些都是构建一个电商系统必不可少的功能。我们一个一个来说每个模块需要实现的功能。

- 商品：维护和展示商品信息和价格。
- 订单：维护订单信息和订单状态，计算订单金额。
- 购物车：维护用户购物车中的商品。
- 支付：负责与系统内外部的支付渠道对接，实现支付功能。
- 库存：维护商品的库存数量和库存信息。
- 促销：制定促销规则，计算促销优惠。
- 用户：维护系统的用户信息，注意用户模块它是一个业务模块，一般不负责用户登录和认证，这是两个完全不同的功能。
- 账户：负责维护用户的账户余额。
- 搜索推荐：负责商城中，搜索商品和各种列表页和促销页的组织和展示，简单的说就是决定让用户优先看到哪些商品。
- 报表：实现统计和分析功能，生成报表，给老板来做经营分析和决策使用。

这里面需要特别说一下促销模块，它是电商系统中，最复杂的一个模块。各种优惠券、满减、返现等等这些促销规则，每个都非常复杂，再加上这些规则叠加计算，常常是复杂到连制定促销规则的人都搞不清楚。

所以每个电商公司无一例外都爆出过，因为促销规则制定失误，而产生非常便宜的“羊毛单”，让精明的消费者薅了“羊毛”。不过五花八门的促销是提升销售最有效的手段，肯定不能因噎废食。

作为系统设计者，我们需要把促销的变化和复杂性封禁在促销模块内部，不能让一个促销模块把整个电商系统都搞得非常复杂，否则就很难去设计和实现。

可行的做法是，把促销模块与其他模块的接口设计的相对简单和固定，这样系统的其他模块就不会因为新的促销玩儿法而改变。

在创建订单时，订单模块把商品和价格信息传给促销模块，促销模块返回一个可以使用的促销列表，用户选择好促销和优惠，订单模块把商品、价格、促销优惠这些信息，再次传给促销模块，促销模块则返回促销价格。

最终生成的订单中，只记录订单使用了哪几种促销，以及最终的促销价就可以了。这样，不管促销这个模块的玩儿法怎么变化，订单和其他模块的业务逻辑不需要随之改变。

至此，我们就完成了一个电商系统的概要设计，你应该对电商系统也有了一个初步的了解。

## 小结

我们每节课的正文结束之后，都会安排一个小结，对课程的重点内容做一个总结。

今天我们再来回顾一下，一个电商系统的设计中，最核心的几个关键点。

首先，系统的角色是：用户、运营人员和老板。这三个角色对电商系统的需求是：用户使用系统来购物，运营人员负责销售商品，老板关注系统中经营数据。电商系统最核心的流程就是用户购物的流程，流程从用户浏览选购商品开始，加购、下单、支付、运营人员发货、用户确认收货，至此流程结束。

细化这个流程之后，我们可以分析出，支撑这个流程几个核心的功能模块：商品、订单、购物车、支付和库存。此外，还需要促销、用户、账户、搜索推荐和报表这些必备的功能模块支撑，才能构成一个完整的电商系统。

我还和你分享了作为一个开发者，你在做需求分析的时候，需要把握的一个要点：不要一上来就设计功能，而是要先理清业务需求，也就是这节课反复强调的两个问题：这个系统是给哪些人用的？他们分别用这个系统来解决什么问题？这样可以确保你做出来的系统，大体上不会偏离用户的预期。

最后，在讲解系统功能模块划分的时候，我们说了一个有效减少系统复杂度的设计经验。那就是，如果系统业务是复杂而多变的，尽量识别出这部分复杂业务的边界，将复杂封禁在一个模块的内部，避免这种复杂度扩散到整个系统中去。

这节课是我们专栏的课前加餐，目的是为了让你了解电商的组成模块。在后续的课程中，我将和你一起经历这个电商系统在从小到大的发展过程中遇到的存储技术问题，并一起解决它。

## 思考题

做完了概要设计，就可以来做技术选型了。作为公司的CTO，课后请你思考一下，这个电商系统的技术选型应该是什么样的？

- 使用什么编程语言和技术栈？
- 需要哪些第三方的框架和云服务？
- 我们最关心的存储系统该怎么选型？

欢迎你在留言区与我讨论，如果你觉得今天的内容对你有帮助，也欢迎把它分享给你的朋友。
