满减折扣促销功能代码优化实战
![](/assets/blank.gif)
点击上方蓝色字体,关注我们
菜哥,YY说你帮她解决了几个问题,也帮我解决一个呗
原来是D妹子,来坐我身边,说下情况
我的项目是个电商项目,现在产品狗要给商品做活动
正常呀
我一个新手初来咋到顶不住压力了,上次来一个折扣活动,现在又来一个满减
正常呀
最要命的两个活动还能叠加使用
正常呀
我写的代码让老大骂了一顿,让我做优化
代码有多烂?
离近一点,我给你看看
好嘞
◆◆背景介绍◆◆
据我所知,几乎所有的互联网公司都带有和电商有关的项目,而且在大多数公司里面还是举足轻重的重头戏,比如京东,淘宝。既然有电商项目,必然会涉及到商品,一旦有商品就会有各种促销活动,比如 满100减20,三八妇女节9折等等类似活动。作为一个coder怎么才能在实现产品狗的需求下,最小改动代码,最优雅的实现呢。今天菜菜不才,就D妹子的问题献丑一番。以下以.netCore c#代码为例,其他语言类似。
◆◆D妹子版本◆◆
首先D妹子有一个商品的对象,商品里有一个价格的属性,价格的单位是分
class Product { //其他属性省略 public int Price { get; set; } }
下面有一个满100减20的活动,在结算价格的时候代码是这样的
public int GetPrice() { Product p = new Product(); int ret = p.Price; if (p.Price >= 100*100) { ret = ret - 20 * 100; } return ret; }
有问题吗?按照需求来说没有问题,而且计算的结果也正确。但是从程序艺术来说,其实很丑陋。现在又有一个全场9折的活动,恰巧有一个商品参与了以上两个活动,而且还可以叠加使用(假设活动参与的顺序是先折扣后满减)。这时候D妹子的代码就变成了这样
public int GetPrice() { Product p = new Product(); //9折活动 int ret = p.Price * 90 / 100; //满减活动 if (ret >= 100 * 100) { ret = ret - 20 * 100; } return ret; }
假如现在又来一个类似活动,那这块代码还需要修改,严重违反了开放关闭原则,而且频繁修改已经上线的代码,bug的几率会大大增高。这也是D妹子领导骂她并且让她codereview的原因。
◆◆优化版本◆◆
那具体要怎么优化呢?修改代码之前,我还是想提醒一下,有几个要点需要注意一点:
1. 商品菜菜认为有一个共同的基类比较好,这样就有了一个所有商品的控制点,为以后统一添加属性留一个入口。好比一个网关系统,为什么会诞生网关这个组件呢,因为有了它我们能方便的统一添加认证,授权,统计等一些列行为。
2. 任何促销的活动最好有一个基类,作用类似商品基类。
3. 对于商品而言,任何促销活动是商品的行为变化点,影响到的是最终的商品价格,所以获取价格这个行为要做特殊的处理。
4. 不同种类的促销活动应该能自行扩展,不会影响别的类型促销活动。
5. 不同种类的促销活动能叠加使用(其实这里涉及到每个活动计算的标准是商品原价还是促销之后价格的问题)。
基于以上几点,首先把商品的对象做一下抽象
//商品抽象基类 abstract class BaseProduct { //商品价格,单位:分 public int Price { get; set; } //获取商品价格抽象方法 public abstract int GetPrice();
} //抽象商品(比如话费商品),继承商品基类 class VirtualProduct : BaseProduct { public override int GetPrice() { return this.Price; } }
接下来活动的基类也需要抽象出来
//各种活动的抽象基类,继承要包装的类型基类 abstract class BaseActivity : BaseProduct {
}
有的同学会问,这里为什么要继承商品的基类呢?主要是为了活动的基类能嵌套使用,这样我就可以实现多个活动同时使用,如果不明白没关系,带着这个问题接着往下看
实现一个打折的活动
//打折活动基类,支持多个商品同时结算 class DiscountActivity : BaseActivity { BaseProduct product = null;
public DiscountActivity(int discount, BaseProduct _product) { Discount = discount; product = _product; }
//折扣,比如 90折 即为90 public int Discount { get; set; } //获取折扣之后的价格 public override int GetPrice() { return product.GetPrice() * Discount / 100; } }
实现一个满减的活动,而且支持自定义满减条件
` class ReductionActivity : BaseActivity { BaseProduct product = null; //满减的对应表 Dictionary<int, int> reductMap = null;
public ReductionActivity(Dictionary<int, int> _redutMap, BaseProduct _product) { reductMap = _redutMap; product = _product; } //获取折扣之后的价格 public override int GetPrice() { var productAmount = product.GetPrice(); //根据商品的总价获取到要减的价格 var reductValue = reductMap.OrderByDescending(s => s.Key).FirstOrDefault(s => productAmount >= s.Key).Value; return productAmount - reductValue; } }
现在我们来给商品做个促销活动吧
VirtualProduct p = new VirtualProduct() { Price=1000}; //打折活动 DiscountActivity da = new DiscountActivity(90, p); var retPrice= da.GetPrice(); Console.WriteLine($"打折后的价格{retPrice}"); //还能叠加参加满减活动 Dictionary<int, int> m = new Dictionary<int, int>() ; m.Add(200, 5); //满200减5 m.Add(300, 10); m.Add(500, 20); m.Add(1000, 50); //这里活动能叠加使用了 ReductionActivity ra = new ReductionActivity(m, da); retPrice = ra.GetPrice(); Console.WriteLine($"打折满减后的价格{retPrice}");
ReductionActivity ra2 = new ReductionActivity(m, ra); retPrice = ra2.GetPrice(); Console.WriteLine($"再打折后的价格{retPrice}");
输出结果:
打折后的价格900打折满减后的价格880再打折后的价格860
现在我们终于能优雅一点的同时进行商品的满减和打折活动了
◆◆进化到多个商品同时促销◆◆
以上代码已经可以比较优雅的能进行单品的促销活动了,但是现实往往很骨感,真实的电商场景中多以多个商品结算为主,那用同样的思路怎么实现呢?
1. 由于这次需要实现的是多商品促销结算,所以需要一个自定义的商品列表来作为要进行结算的对象。此对象行为级别上与单品类似,有一个需求变化点的抽象:获取价格
//商品列表的基类,用于活动结算使用 class ActivityListProduct : List<BaseProduct> { //商品列表活动结算的方法,基类必须重写 public virtual int GetPrice() { int ret = 0; base.ForEach(s => { ret += s.GetPrice(); }); return ret; } }
2. 把多商品促销活动的基类抽象出来,供不同的促销活动继承使用,这里需要继承ActivityListProduct,为什么呢?和单品的类似,为了多个子类能够嵌套调用
//商品列表 活动的基类,继承自商品列表基类 internal abstract class BaseActivityList : ActivityListProduct {
}
3. 创建一个打折和满减活动
//打折活动基类,支持多个商品同时结算 class DiscountActivityList : BaseActivityList { ActivityListProduct product = null; public DiscountActivityList(int discount, ActivityListProduct _product) { Discount = discount; product = _product; } //折扣,比如 90折 即为90 public int Discount { get; set; } public override int GetPrice() { var productPrice = product.GetPrice(); return productPrice * Discount / 100; } } //满减的活动 class ReductionActivityList : BaseActivityList { ActivityListProduct product = null; //满减的对应表 Dictionary<int, int> reductMap = null;
public ReductionActivityList(Dictionary<int, int> _redutMap, ActivityListProduct _product) { reductMap = _redutMap; product = _product; } //获取折扣之后的价格 public override int GetPrice() { var productAmount = product.GetPrice(); //根据商品的总价获取到要减的价格 var reductValue = reductMap.OrderByDescending(s => s.Key).FirstOrDefault(s => productAmount >= s.Key).Value; return productAmount - reductValue; } }
先来一波多商品促销活动
VirtualProduct p = new VirtualProduct() { Price = 1000 }; VirtualProduct p2 = new VirtualProduct() { Price = 1000 }; ActivityListProduct lst = new ActivityListProduct(); lst.Add(p); lst.Add(p2); DiscountActivityList dalist = new DiscountActivityList(80, lst); Console.WriteLine($"打折后的价格{dalist.GetPrice()}"); DiscountActivityList dalist2 = new DiscountActivityList(90, dalist); Console.WriteLine($"打折后的价格{dalist2.GetPrice()}");
DiscountActivityList dalist3 = new DiscountActivityList(90, dalist2); Console.WriteLine($"打折后的价格{dalist3.GetPrice()}");
//还能叠加参加满减活动 Dictionary<int, int> m = new Dictionary<int, int>(); m.Add(200, 5); //满200减5 m.Add(300, 10); m.Add(500, 20); m.Add(1000, 50);
ReductionActivityList ral = new ReductionActivityList(m, dalist3); Console.WriteLine($"再满减打折后的价格{ral.GetPrice()}");
结算结果:
打折后的价格1600打折后的价格1440打折后的价格1296再满减打折后的价格1246
现在基本上可以让D妹子不被挨骂了吧~~
分享 Java 常见面试题及答案(上)
分享 Java 常见面试题及答案(下)
公众号欢迎各位大佬投稿
今日话题(第25天)
今日思考,你有过为了适用更多业务场景,做过一次代码优雅的优化吗?学编程的都知道,面向对象开发有三大特征:封装、继承、多态,谈谈对这三者的理解?两个话题选择其一打卡即可。每天文末的话题讨论打卡,就是希望大家多交流,每个人都有在公众号发言的权力!希望你和我一起在这里成长!
点击「写留言」分享你的看法吧~
公众号日更,欢迎关注!
如果文章不错,欢迎转发!
点击阅读原文获取2000G视频资料
满减折扣促销功能代码优化实战相关推荐
- 电商产品设计:谈谈促销功能的实现逻辑
电商产品设计:谈谈促销功能的实现逻辑 七月订阅专栏取消订阅 汪汪社区里的一只喵. 2017-07-12 1.5万 170 23 产品经理就业班,12周特训,测.练.实战,22位导师全程带班,200+名 ...
- 满减优惠用多了,想过怎么运作的吗?
本文内容逻辑图 本文重点分析电商满减营销产品. 行文逻辑分为三大模块:1.基本概念:2.详细动线分析:3.建议.其中动线分析为重点. 一. 满减营销产品的基本概念 (一)满减产品的类型 满减优惠卷: ...
- 电商平台营销活动玩法大全、拓客、吸粉、裂变、引流、团购返现、限时折扣、找人代付、砍价代付、多人拼团、优惠套餐、秒杀折扣、满减优惠、电商营销、电商推广、商品促销、营销红包、Axure原型、rp原型
电商平台营销活动玩法大全.拓客.吸粉.裂变.引流.团购返现.限时折扣.找人代付.砍价代付.多人拼团.优惠套餐.秒杀折扣.满减优惠.电商营销.电商推广.商品促销.营销红包.Axure原型.rp原型 Ax ...
- 【Lilishop商城】No3-11.模块详细设计,促销模块(优惠券、满减、秒杀、积分)的详细设计
仅涉及后端,全部目录看顶部专栏,代码.文档.接口路径在: [Lilishop商城]记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口 ...
- 2022年京东618活动规则:618满减规则为299减50
2022年京东618活动的活动时间.满299减50规则,以及618红包领取攻略 就在今天(5月23)京东618年中大促活动店庆日预售开启了,本文我们一起来看看2022年京东618活动的活动时间.满29 ...
- 弘辽科技:淘宝四月份有满减活动吗?淘宝每个月都会有满减活动吗
网购是现在主流的购物方式,很多的人都愿意在网上消费,一是因为网上商品种类多能够满足大家购物需求,二是电商经常搞活动,价格很吸引人,那淘宝4月份有满减活动吗?接下来小编就来给大家讲解一下这方面的内容. ...
- 优惠券使用/凑满减优惠/硬币组合问题(结果包括最优组合和最优值)
DP法求满减优惠组合问题 一.原问题描述 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别 ...
- 电商平台满减活动需求分析
现如今,随着互联网的深入,各大电商平台也是多如牛毛,那么入职到了电商平台后,对于各种满减活动,该如何测试呢. 今天就给大家说道说道,如果有写得不对的地方,欢迎大家指正. 一: 各大电商网站常用的满减方 ...
- 2021年淘宝双11跨店满减如何使用?
2021年淘宝双11跨店满减怎么使用? 前面小编赵一八笔记介绍了天猫双十一活动从几号开始到几号结束,双十一活动期间淘宝的商家也会上线促销活动,其中跨店满减是少不了的环节,大家知道今年淘宝双11满多少减 ...
最新文章
- Jquery获取参数(解决参数中文乱码问题)
- 【收藏】在QGIS中导入GOOGLE、BING等地图和卫星影像(插件方式和XYZ方式)
- 深入理解Python生成器(Generator)
- C++11 并发指南一(C++11 多线程初探)
- Bzoj5093: 图的价值
- Windows函数错误处理
- 关于CMS垃圾回收器的几个问题
- bzoj1069 [SCOI2007]最大土地面积 凸包+单调性
- 轨迹跟踪主要方法_带你入门多目标跟踪(一)领域概述
- 最优化读书笔记R(一)
- java中volatile关键字的含义_Java里volatile关键字是什么意思
- 看图说说class文件结构(部分)
- Python进阶(零)字典、缺省参数、多值参数
- 计算机发展简史ppt教程,计算机发展简史ppt课件.ppt
- PCB Layout总结
- angular uibpagination 分页相关
- 《领域驱动设计》学习笔记
- realsense ros 三维点云地面检测与障碍物聚类
- 天下3 最多的服务器,《天下3》服务器合并规则
- 大豆SNP位点查找V2.0
热门文章
- 使用JAVA调用热敏打印机接口实现打印功能
- Vim/Neovim ALE system verilog使用xvlog时出现“ ‘logic‘ is uan unknown type “ 等
- 你永远不知道用户怎么使用你的产品
- 医院pacs系统服务器配置,浪潮为千佛山医院PACS系统开“药方”
- 学计算机语言从何开始,小孩学编程从哪开始
- 自然语言处理nlp小姜机器人(闲聊) nlp_xiaojiang-996station GitHub鉴赏官
- cyusb3014 设备插入 westbridge未识别问题220514
- matlab 边缘检测 抠图,ps如何调整边缘的流程:边缘检测、调整边缘、输出(调整边缘抠图...
- ASO关键词优化技巧:如何充分利用热搜榜与相关热点?
- idea 一直 performing vcs refresh