设计原则实战—电商平台积分系统

需求背景

设计一个简单的电商平台积分系统

需求分析

借鉴竞品

先去借鉴一下其他电商平台的积分系统是怎么设计的,可以去使用一下淘宝的积分系统或者百度搜一下"淘宝积分兑换规则",就能摸清积分系统大致的功能。

积分系统的功能简单分成两类:积分的赚取渠道和兑换规则,赚取渠道比如有下单、签到、答题等,兑换规则比如有签到送10积分,答题全对送10积分,下单后返送某个下单金额比例的积分等;积分的消费渠道和兑换规则,消费渠道比如有下单抵钱、换优惠券等,兑换规则比如下单时按照某个比例抵扣用户拥有的积分、10积分换一张特定的优惠券等

挖掘细节

上面只是积分系统的简单功能,我们还需要根据产品的线框图、用户用例来细化流程,挖掘一些细节的、不容易想到的功能点

用户用例比如侧重情景化,描述了用户怎么使用我们的产品,在特定场景下完成一个功能的所有流程,包含更多细节让人更容易理解。比如积分有效期的用户用例,可以进行如下的设计:
1)用户赚取积分的时候,告知用户有效期
2)用户消费积分的时候,优先消费快过期的积分
3)用户查询积分明细的时候,显示积分的有效期和状态(是否过期)
4)用户查询总可用积分的时候,去掉已过期的积分

分析后,系统整体的功能如下:
1)积分的赚取渠道和兑换规则
2)积分的消费渠道和兑换规则
3)可用积分查询、积分明细查询

系统设计

划分模块,设计每个模块的接口、数据库、业务模型

合理地把功能划分到不同的模块

把相似的功能划到一个模块,不相似的功能划到不同的模块,使得整个模块设计"高内聚、低耦合",模块之间的关系简单、清晰

那怎么看模块划分的是否合理呢?
实现一个功能的时候,如果需要跨团队、跨部门、跨系统沟通,那么就说明模块设计的不合理,功能不够内聚
为了避免业务知识耦合,让下层模块一般比较通用,所以下层模块不要感知上层模块的业务逻辑,上层模块可以感知下层模块的一些业务逻辑

划分方式:
1)把积分赚取渠道和兑换规则、积分消费渠道和兑换规则的管理单独划分成一个营销系统,积分系统只负责积分的增删改查
2)把积分赚取渠道和兑换规则、积分消费渠道和兑换规则的管理划分到各个上层业务的系统,比如订单系统、优惠券系统等,订单系统只负责积分的增删改查
3)积分系统负责积分赚取渠道和兑换规则、积分消费渠道和兑换规则的管理以及积分的增删改查

根据我们开头提到划分思想,可以采用第一种、第二种划分方式,因为第三种划分方式积分系统需要感知订单、优惠券的各种兑换规则,下层系统感知到了上层系统的业务知识

这里我个人偏向第一种方式,因为这种方式将积分赚取、消费的管理内聚在一个营销系统模块中,修改的时候可以更集中

设计模块之间的交互关系

模块之间的交互关系分为两种:接口同步调用、消息中间件异步调用。同步调用的好处是简单直接、异步调用的好处是解耦

上层模块调用下层模块使用同步调用(因为上层模块、下层模块本身就不怎么耦合,所以可以简单直接一点),同层模块之间的调用使用异步调用进行解耦(避免同层模块耦合)

设计模块的接口、数据库、业务模型

数据库设计:

这里只需要一张积分流水明细表即可,记录用户每一笔积分的赚取和消费。

表设计

表名credit_transaction
id主键ID
chan_id操作渠道ID,比如下单、评论等
event_id事件ID,比如订单ID、评论ID等
credit积分操作,正数代表赚取,负数代表消费
op_user操作人
expire_time积分的过期时间
create_time创建时间即操作时间
接口设计

接口设计要满足单一职责原则,粒度越小越通用,但是粒度小会带来一些问题
1)实现一个功能可能需要调用多个小的接口,涉及多次网络传输,性能差并且调用繁琐
2)多个接口调用如果要保证所有接口调用操作的原子性,那么需要使用分布式事务,成本很大

所以,我们可以采用facade门面模式在职责单一的细粒度接口的基础上封装一层粗粒度接口提供给外部使用
对于积分系统,我们需要提供如下几个接口:
1)积分新增 CreditIncrease(userID int, credit int)
2)积分扣减 CreditDecrease(userID int, credit int)
3)可用积分查询 CreditFind(userID int)

业务模型

采用MVC三层架构,Controller、Service、Repository

为什么要采用分层架构呢?
  1. 代码复用
    一个Service可以被多个Controller重复使用
  2. 隔离变化
    Repository层就将数据库的操作封装起来,只对外暴露数据操作的接口,Service层只需要使用数据操作接口不需要关注底层数据的操作逻辑,即使底层数据源由Mysql切换为Redis、由Mysql切换为ES也不会影响到Service层
    Controller、Service、Repository这三层的稳定程度是不一样的,Repository是面向数据库的,数据库的结构变更频率是很小的,所以Repository层代码最稳定
    而Controller层是面向用户需求的,用户需求的变更频率是很大的,所以Controller层代码是最不稳定的。分层后,Controller层的代码变更不会影响到最稳定的Repository层
  3. 隔离关注点
    每一层只需要关注自己负责的事情,层与层之间通过接口进行数据传输
    Repository层只负责数据的操作
    Service层只负责处理业务逻辑
    Controller层只负责接收用户请求、校验参数、编排多个Service层接口、组装VO对象
  4. 可测试性好
    Repository层通过依赖注入的方式注入到Service层,这样我们就可以Mock Repository层的接口,将Mock的接口注入到Service,使用我们自己Mock的数据
  5. 应对系统复杂性
    如果不分层,所有代码都在一个类里面,随着业务需求的迭代这个类的代码会非常多,就会导致可读性、可维护性急剧下降,应对复杂度最有效的办法就是拆分。
    拆分分为水平拆分、垂直拆分,水平拆分就是按照业务功能拆分即划分模块,垂直拆分就是分层
BO、VO、Entity存在的意义是什么?

VO、BO、Entity分别是Controller层、Service层、Repository层定义的数据对象,实际开发中,它们可能存在大量重复的字段,甚至包含的字段一模一样
但是它们的功能语义是不一样的,所以不违反DRY原则。每层维护自己的数据对象,上下层之间通过接口进行通信,下层将自己的数据对象传给上层后,上层转换成自己的数据对象进行使用,这样每层之间都不耦合,结构更加清晰

如何解决数据对象代码重复的问题?

可以采用继承,将多个数据对象公共的字段抽到父类里面,多个数据对象都继承这个父类,因为继承关系也就一层所以继承结构也不复杂

如何解决数据对象转换问题?

可以使用一些工具包比如copier来进行数据对象转换,这样就不需要手动复制字段了

一些框架的规范是要求对象的字段都是大写,这样这些框架才可以对对象进行操作,所以为了便捷性,BO、VO、Entity的字段都需要大写,这样会破坏对象原有的封装性,只能靠程序员自己来保证对象不被错误使用

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,我可以为您提供一份Vue项目实战电商后台管理系统的总体设计方案。 1. 项目概述 本项目是一款基于Vue.js框架开发的电商后台管理系统,主要面向电商企业的后台管理人员,提供商品管理、订单管理、用户管理等核心功能,帮助企业实现电商业务的管理。 2. 技术栈 Vue.js、Element-UI、Axios、Node.js、Express、MongoDB等。 3. 功能模块 - 登录和权限管理:用户登录系统需要进行身份验证,管理人员可以根据用户角色设置权限,以保证系统的安全性。 - 商品管理:管理人员可以对商品进行添加、删除、修改、查询等操作,同时可以对商品进行分类、上下架等操作。 - 订单管理:管理人员可以查看订单的详细信息、处理订单、退款等操作。 - 用户管理:管理人员可以查看用户的详细信息、管理用户账户等。 - 数据统计:系统将会从多个维度进行数据统计,并提供数据图表展示,以便管理人员能够清晰地了解业务情况。 4. 技术实现 - 前端部分:使用Vue.js框架,搭配Element-UI组件库进行页面UI开发,使用Axios进行数据交互。 - 后端部分:使用Node.js搭配Express框架进行服务端开发,使用MongoDB作为数据库存储数据。 - 数据交互:前端通过Axios向后端发送请求,后端通过Express进行处理并返回数据给前端。 - 权限管理:使用JWT实现用户身份验证,通过中间件进行路由权限控制。 - 数据统计:使用ECharts进行数据图表展示,从多个维度对数据进行统计分析。 5. 总结 本文为您提供了一份Vue项目实战电商后台管理系统的总体设计方案,针对不同的场景和需求,可以进行适当的调整和改进。希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值