应用设计 Practice
1. thought
实际应用设计,首先还是需要将工作进行合理分割:
2.1 业务需求
功能点
- 赚取积分
- 积分赚取渠道
- 订单
- 签到
- 评论
- 积分兑换规则
- 订单金额与积分的兑换比例
- 签到赠送积分数量等
- 积分赚取渠道
- 消费积分
- 积分消费渠道
- 抵扣订单金额
- 兑换优惠券
- 积分换购
- 参与活动
- 积分消费渠道
- 赚取积分
方式方法
- 借鉴已经相对成熟的产品
- 看其实现的方式方法
- 通过产品线框图
- user case
- 模拟用户是如何使用我们的产品的
- 描述用户在特定的应用场景当中的一个完整的业务操作流程
- 借鉴已经相对成熟的产品
2.2 系统设计
2.2.1 功能模块划分
- 将功能划分到不同的模块当中
- 做到模块层面的高内聚,低耦合
- 针对上述的业务需求,我们可以采用
- 将关于积分的赚取消费的规则的管理维护放到更上层的营销系统当中,这样积分系统就只负责增删改查的数据库操作了
- 将规则分散到各个子系统当中,譬如订单系统,评论系统,签到系统,诸如此类
- 所有功能划分到积分系统当中
值得注意的是,为了避免业务知识的耦合,让下层系统更加通用,我们不希望下层系统(被调用系统)包含太多上层系统(调用系统)的业务信息。但上层系统是可以包含下层系统的业务信息的,比如,订单系统、优惠券系统、换购商城等作为调用积分系统的上层系统,可以包含一些积分相关的业务信息。但是,反过来,积分系统中最好不要包含太多跟订单、优惠券、换购等相关的信息。
因此,1,2都是相对不错的选择,我们希望做的是让积分系统模块只包含积分的增删改查的操作,而不包含太多的业务层面的逻辑。
2.2.2 模块间交互
定位需要和积分系统之间进行交互的系统,以及交互方式。
一般来说,系统之间的交互方式有两大类:
- 同步接口调用
- 利用信息中间件异步调用
2.2.3 设计模块的接口、数据库、业务模型
数据库和接口的设计相对来说都比较重要,一旦设计好,都不能轻易改动。尤其是当有不同的组来调用你的API的时候,让所有的组都快速迁移到新的API上是一件相对比较困难的事情了。 改动数据库表的结构,需要涉及数据的迁移和适配。
而业务模型,即业务逻辑代码,因为都是内部使用,改动的可能性比较大,对外是不可见的。
数据库设计:
- id - 明细ID
- user_id - 用户ID
- channel_id - 赚取或消费渠道ID
- event_id - 相关事件ID,例如订单ID,评论ID,优惠券换购ID等
- credit - 积分
- create_time - 积分赚取或消费时间
- expired_time - 积分过期时间
接口设计
- 单一职责原则
- 但是粒度太小也不好,比如一个功能的实现需要多个接口,但是每个接口如果都是RPC的一次远程调用的话,那网络上的损耗就很多,多次远程调用会影响性能的
- 另外还有数据一致性 - 即操作的原子性方面的考量
- 可以借鉴facade外观设计模式,在职责单一的细粒度接口之上,封装一层粗粒度的接口给外部使用
- 单一职责原则
MVC
- controller负责接口暴露
- service 负责核心业务逻辑
- repository负责数据读写
- 为什么要分成MVC三层?
- 代码复用
- 隔离变化
- 隔离关注点
- 提高代码的可测试性
- 能够应对系统的复杂性
3. 非业务通用框架设计
假设我们要设计开发一个小框架,来获取接口调用的各种统计信息。
- 响应时间
- max/ min/ avg/ percentile/ count/ tps
3.1 需求分析
是一个和业务无关的独立功能,我们可以将其开发成一个独立的框架或者库,集成到很多的业务系统当中。作为一个需要复用性的框架,除了功能上的需求以外,非功能性的需求也非常重要。
功能性需求分析
接口统计信息
- 响应时间
- 接口调用次数
统计信息的类型
- max min ave percentile tps count
统计信息显示格式
- json
- html
- 自定义
统计信息显示终端
- console
- http 页面
- 日志
- 自定义
统计触发方式
统计时间区间
统计时间间隔
非功能性需求分析
易用性
- 框架是否易集成,易拔插
- 跟业务代码是否为松耦合
- 提供的接口是否足够灵活
性能
- 不希望框架本身的代码执行效率会对业务系统有太多性能上的影响
- 希望框架低延迟,并且对内存的消耗不能太大
扩展性
- 在不修改或者尽量少修改代码的情况下添加新功能的能力
容错性
通用性
- 除了接口数据统计,能否将其放到其他事件上来做统计呢?
3.2 框架设计
可以借鉴TDD (测试驱动开发)和Prototype(最小原型)的思想,先聚焦于一个简单的应用场景,基于此来设计一个简单的原型,然后不断进行迭代。
而后是将整个框架分为多个模块,分模块进行思考:
- 数据采集
- 打点采集原始数据
- 记录每次接口请求的响应时间和请求时间
- 数据采集过程要高度容错,不能影响到接口本身的可用性
- 存储
- 负责将采集的原始数据保存下来,以便后面做聚合统计
- 数据可以存储在
- redis
- mysql
- hbase
- 日志
- 文件
- 内存
- 聚合统计
- 将原始数据聚合为统计数据
- 显示
- 将统计数据以某种格式显示到终端当中
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com
文章标题:应用设计 Practice
文章字数:1.7k
本文作者:Leilei Chen
发布时间:2020-05-18, 04:03:10
最后更新:2020-05-20, 08:12:33
原始链接:https://www.llchen60.com/%E5%BA%94%E7%94%A8%E8%AE%BE%E8%AE%A1-Practice/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。