本地购物车的实现分析

本文最后更新于 2021年4月4日 晚上

在公司遇到要实现一个本地购物车的需求, 经常都说购物车实现非常简单, 实际上有时状态一多就略显蛋疼了. 好在有状态模式, 以及在 Head First 上看到的分析方法, 才完成这个购物车的实现, 现将过程记录.

需求描述

在客户端中实现一个本地购物车, 本地购物车需要有如下功能:

  • 用户可以在程序中多个位置利用”添加商品”按钮将商品加入到购物车中, 每点击一次商品对应的”添加商品”按钮, 购物车中就添加一个该商品(如果商品存在, 则将其选择数量加 1).

  • 用户可以点击”购物车”按钮进入购物车界面

  • 用户可以在购物车界面中移除单个商品

  • 用户可以在购物车界面中移除全部商品

  • 用户可以在购物车界面中勾选(或全选)商品

  • 用户可以在购物车界面中反选(或全不选)商品

  • 用户可以在购物车界面中修改任意商品当前购买数量

  • 需要限制用户购买数量最小是 1, 最大不超过库存数量或最大可购买数量.

  • 若用户勾选了某个(或某些)商品, 且其他商品中存在和当前已勾选商品互斥的商品(不能同时购买的商品), 则用户不能在界面中勾选这些互斥商品(勾选按钮不可用).

  • 若用户选择的商品中存在互斥商品(不能同时购买的商品), 则不能全选.

  • 若用户反选了某个商品, 需要重新计算当前选择集中的互斥商品列表, 并刷新不能勾选的互斥商品的列表, 从而刷新界面内商品的可选择状态.

  • 需要在购物车界面中显示当前用户勾选的所有商品的总价, 折扣价, 以及总价折扣价差.

  • 如果当前购物车中所有商品可以同时购买, 则进入购物车时自动将所有商品进行一个全选操作.

  • 如果当前购物车中有商品间存在互斥, 则进入购物车时所有的商品都是未勾选状态, 且用户无法进行全选和全反选操作.

  • 如果用户删除了某个(或某些)商品, 且购物车全部商品中不存在相互互斥的商品后, 则可以让用户进行全选和反选操作.

可以看到, 购物车中实际上有如下几块内容:

  1. 商品条目的增加和删除

  2. 商品购买数量的修改

  3. 商品的选中状态以及是否可以被选中

  4. 已勾选商品的价格计算

下面就来看看分析的办法.

购物车状态分析

和购物车相关的状态及操作如下图所示:

可以看到, 实际上整个购物车的状态并不复杂, 有如下状态:

  1. 无商品状态(空购物车)

  2. 只有一个商品: 剥离出来这个状态是为了更好地处理有无互斥商品的情况, 只有一个商品时, 是不可能存在互斥商品条件的, 且购物车需要在有互斥和无互斥状态下进行切换.

  3. 有大于一个商品且商品中无互斥商品

  4. 有大于一个商品且商品中有互斥商品

有如下可以对购物车进行的操作:

  1. 添加单个商品

  2. 移除单个商品

  3. 移除全部商品

针对购物车中的互斥商品判断, 独立一个互斥判断器即可, 每次操作如果需要判断互斥状态, 都利用互斥判断器来判断, 购物车中仅维护一个当前选择的商品条目及对应数量的列表即可.

限制商品的最小购买数量是 1, 也简化了一些操作, 这样的话商品数量的改变就不会引起购物车状态改变了, 购买数量设置操作主要有如下:

  1. 增加购买数量 1

  2. 减少购买数量 1

  3. 设置购买数量(最少 1 个, 最大不超过库存或允许购买的最大值)

上述就可以支撑起购物车的整个骨架了, 但还有一个大的方面, 就是购物车中的商品勾选, 勾选互斥, 以及勾选价格计算.

商品勾选处理

商品的勾选管理最好是独立出来, 这样能够保证职责划分更清晰, 且实现更简单.

商品互斥条件计算

在商品中携带了 ID, 通过它即可查询商品数据源中对应的商品, 进而获知该商品的互斥类别, 互斥规则是在程序启动时从服务器获取到的, 通过互斥规则和已有的商品互斥类别, 就可以计算出购物车中是否存在互斥商品, 以及和当前已勾选商品互斥的其他商品列表.

互斥也独立出一个互斥判断器来实现.

商品价格计算

商品中携带的 ID 查询出对应商品, 通过商品的类别以及购买的数量, 即可计算出商品总价, 这里也通过一个独立的价格计算器去实现.

组装成一个完整的购物车实现

外界只能够通过购物车提供的接口来访问特定功能, 所以需要把上述内容都组装起来, 组装的载体就是购物车类. 所有内容如下所示:

  1. 购物车接口

  2. 购物车类

  3. 勾选管理器类

  4. 互斥判断器类

  5. 价格计算器类

特别需要注意: 由于将勾选管理独立出来了, 如果购物车中的某个商品被删除, 则需要先在勾选管理器中将对应商品执行反选操作, 这样才能保证结果的一致.

实践出真知

如果要检验这样的设计是否合理, 最好的办法就是编写出来看看, 特别是要检验一下把勾选管理独立出来的合理性.


本地购物车的实现分析
https://blog.rayy.top/2018/10/21/2019-15-shoppingcart-analyse/
作者
貘鸣
发布于
2018年10月21日
许可协议