如何用设计模式减少代码冗余?附真实项目案例解析
你有没有遇到过这种情况?每次新增个支付渠道就要复制粘贴整段校验代码,改三个地方才能生效。或者看到同事写的订单模块,和自己刚做完的优惠券模块有70%代码长得一模一样…??程序员接私活??可能要看技术广度,但在职场生存必须掌握??消灭代码重复??的真本事。今天咱们就聊点能直接照抄的实战案例,看完马上能用。
??场景一:支付渠道多到爆炸怎么办???
上个月接手个电商项目,微信支付、支付宝、银联支付三个渠道的校验逻辑各自为战。每次加新渠道都得重写校验规则,搞得人想砸键盘。这时候就该请出??策略模式??了。
具体怎么操作?三步走:
- 把各个渠道的校验方法抽出来,单独做成类(比如WechatValidator、AlipayValidator)
- 搞个统一的校验接口Validator,定义validate()方法
- 用个上下文类根据支付类型自动切换校验策略
举个栗子,原先处理微信支付要这么写:
java复制if(payType == "wechat"){ // 200行校验逻辑 } else if(payType == "alipay"){ // 180行相似代码 }
改成策略模式后:
java复制Validator validator = ValidatorFactory.create(payType); validator.validate(request);
这样新增个抖音支付渠道,只需要加个DouyinValidator类就完事了,完全不用碰原有代码。是不是突然觉得策略模式真香?
??场景二:订单流程像俄罗斯套娃??
做电商系统的肯定懂,创建订单→扣库存→发通知这套流程,在普通订单、秒杀订单、团购订单里反复出现。每次改个公共步骤,得在十来个地方同步修改,是不是很头大?
这时候就该用??模板方法模式??。去年做跨境电商项目时,我们这么搞:
- 在抽象类OrderTemplate里写死流程骨架
- 把差异步骤声明成抽象方法
- 普通订单继承后实现calcShippingFee(),海外订单继承后实现calcTax()
比如发货通知这个步骤,原先在各个订单类型里重复了8次:
python复制# 普通订单发货 def ship_normal(): # 50行公共代码 send_sms() # 单独定制点 # 海外订单发货 def ship_oversea(): # 同样的50行公共代码 send_email() # 不同点
用模板方法改造后:
python复制class OrderTemplate: def ship(self): self.packaging() # 公共方法 self.notify() # 抽象方法 class NormalOrder(OrderTemplate): def notify(self): send_sms() class OverseaOrder(OrderTemplate): def notify(self): send_email()
现在要加个直播订单类型?直接继承模板类,实现自己的通知方式就行,再也不用在屎山里扒拉代码了。
??场景三:日志记录到处乱塞??
上周排查个线上bug,发现同事在20多个Controller里都写了同样的日志记录代码。这种分散式写法,想统一调整日志格式简直要命。这时候??装饰器模式??就该登场了。
具体怎么救场?拿Spring Boot项目举例:
- 创建个@Logging注解
- 写个AOP切面拦截带注解的方法
- 在切面里统一处理入参出参日志
改造前后对比:
改造前 | 改造后 |
---|---|
每个方法里手动写log.info() | 方法上加个@Logging注解 |
改日志格式要全局搜索替换 | 只改AOP切面里的1处 |
新人容易忘记写日志 | 强制统一日志规范 |
有兄弟要问:那有些特殊方法不需要记录怎么办?简单,用@Logging注解的exclude参数就能搞定,比在代码里写if判断清爽多了。
这时候肯定有人要抬杠:设计模式这么麻烦,我直接复制粘贴不是更快?去年重构个供应链系统时,发现有段计算运费的代码在15个地方重复。结果政策调整导致运费规则变更时,实习生漏改了3处,直接造成30多万损失。用设计模式虽然前期多花2小时,但后续维护成本能砍掉80%。
小编观点:别把设计模式当八股文,它们就是程序员日常打架用的趁手兵器。遇到相似代码块别急着复制,先想想是不是哪个模式能套用。刚开始可能会觉得笨手笨脚,但就像学骑自行车,摔几次就会了。下次写重复代码前,先抽根烟冷静下,说不定就能发现模式的应用场景了呢?
本文由嘻道妙招独家原创,未经允许,严禁转载