Spring MVC 必备设计模式 策略模式

策略模式(Strategy)

就是⼀个问题有多种解决⽅案,选择其中的⼀种使⽤,这种情况下我们
使⽤策略模式来实现灵活地选择,也能够⽅便地增加新的解决⽅案。⽐如做数学题,⼀个问题的
解法可能有多种;再⽐如商场的打折促销活动,打折⽅案也有很多种,有些商品是不参与折扣活
动要按照原价销售,有些商品打8.5折,有些打6折,有些是返现5元等。

结构

策略(Strategy)
定义所有⽀持算法的公共接⼝。 Context 使⽤这个接⼝来调⽤某 ConcreteStrategy 定义的算法。
策略实现(ConcreteStrategy)
实现了Strategy 接⼝的具体算法
上下⽂(Context)
维护⼀个 Strategy 对象的引⽤
⽤⼀个 ConcreteStrategy 对象来装配
可定义⼀个接⼝⽅法让 Strategy 访问它的数据

示例

假如现在有⼀个商场优惠活动,有的商品原价售卖,有的商品打8.5折,有的商品打6折,有的返现
5元

package designpattern.strategy.old;
import java.text.MessageFormat;
public class BuyGoods {
 private String goods;
 private double price;
 private double finalPrice;
 private String desc;
 public BuyGoods(String goods, double price) {
 this.goods = goods;
 this.price = price;
 }
 public double calculate(String discountType) {
 if ("discount85".equals(discountType)) {
 finalPrice = price * 0.85;
 desc = "该商品可享受8.5折优惠";
 } else if ("discount6".equals(discountType)) {
 finalPrice = price * 0.6;
 desc = "该商品可享受6折优惠";
 } else if ("return5".equals(discountType)) {
 finalPrice = price >= 5 ? price - 5 : 0;
 desc = "该商品可返现5元";
 } else {
 finalPrice = price;
 desc = "对不起,该商品不参与优惠活动";
 }
 System.out.println(MessageFormat.format("您购买的商品为:{0},原价为:
{1}{2},最终售卖价格为:{3}", goods, price, desc, finalPrice));
 return finalPrice;
 }
}

测试

package designpattern.strategy.old;
public class Test {
 public static void main(String[] args) {
 BuyGoods buyGoods1 = new BuyGoods("Java编程思想", 99.00);
 buyGoods1.calculate("discount85");
 BuyGoods buyGoods2 = new BuyGoods("罗技⿏标", 66 );
 buyGoods2.calculate("discount6");
 BuyGoods buyGoods3 = new BuyGoods("苹果笔记本", 15000.00);
 buyGoods3.calculate("return5");
 BuyGoods buyGoods4 = new BuyGoods("佳能相机", 1900);
 buyGoods4.calculate(null);
 }
}

上述代码可以解决问题,但是从代码设计的⻆度还是存在⼀些问题

  • 增加或者修改打折⽅案时必须修改 BuyGoods 类源代码,违反了⾯向对象设计的 “开闭原 则”,代码的灵活性和扩展性较差。
  • 打折⽅案代码聚合在⼀起,如果其他项⽬需要重⽤某个打折⽅案的代码,只能复制粘贴对应
    代码,⽆法以类组件的⽅式进⾏重⽤,代码的复⽤性差。
  • BuyGoods 类的 calculate() ⽅法随着优惠⽅案的增多会⾮常庞⼤,代码中会出现很多if分 ⽀,可维护性差。

此时,我们可以使⽤策略模式对 BuyGoods 类进⾏重构,将打折⽅案逻辑(算法)的定义和使⽤
分离。
抽象策略类 AbstractDiscount,它是所有具体打折⽅案(算法)的⽗类,定义了⼀个 discount
抽象⽅法

package designpattern.strategy.now.discount;
public abstract class AbstractDiscount {
 public double getFinalPrice() {
 return finalPrice;
 }
 public void setFinalPrice(double finalPrice) {
 this.finalPrice = finalPrice;
 }
 public String getDesc() {
 return desc;
 }
 public void setDesc(String desc) {
 this.desc = desc;
 }
 protected double finalPrice;
 protected String desc;
 public IDiscount(String desc) {
 this.desc = desc;
 }
 public abstract double discount(double price);
}

四种具体策略类,继承⾃抽象策略类 AbstractDiscount,并在 discount ⽅法中实现具体的打折
⽅案(算法)

package designpattern.strategy.now.discount.impl;
import designpattern.strategy.now.discount.AbstractDiscount;
public class Discount85 extends AbstractDiscount {
 public Discount85() {
 super("该商品可享受8.5折优惠");
 }
 @Override
 public double discount(double price) {
 finalPrice = price * 0.85;
 return finalPrice;
 }
}



package designpattern.strategy.now.discount.impl;
import designpattern.strategy.now.discount.AbstractDiscount;
public class Discount6 extends AbstractDiscount {
 public Discount6() {
 super("该商品可享受6折优惠");
 }
 @Override
 public double discount(double price) {
 finalPrice = price * 0.6;
 return finalPrice;
 }
}



package designpattern.strategy.now.discount.impl;
import designpattern.strategy.now.discount.AbstractDiscount;
public class Return5 extends AbstractDiscount {
 public Return5() {
 super("该商品可返现5元");
 }
 @Override
 public double discount(double price) {
 this.finalPrice = price >= 5 ? price - 5 : 0;
 return finalPrice;
 }
}


package designpattern.strategy.now.discount.impl;
import designpattern.strategy.now.discount.AbstractDiscount;
public class NoDiscount extends AbstractDiscount {
 public NoDiscount() {
 super("对不起,该商品不参与优惠活动");
 }
 @Override
 public double discount(double price) {
 finalPrice = price;
 return finalPrice;
 }
}

类 BuyGoods,维护了⼀个 AbstractDiscount 引⽤

package designpattern.strategy.now;
import designpattern.strategy.now.discount.AbstractDiscount;
import java.text.MessageFormat;
public class BuyGoods {
 private String goods;
 private double price;
 private AbstractDiscount abstractDiscount;
 public BuyGoods(String goods, double price, AbstractDiscount
abstractDiscount) {
 this.goods = goods;
 this.price = price;
 this.abstractDiscount = abstractDiscount;
 }
 public double calculate() {
 double finalPrice = abstractDiscount.discount(this.price);
 String desc = abstractDiscount.getDesc();
 System.out.println(MessageFormat.format("商品:{0},原价:{1}{2},最
终价格为:{3}", goods, price, desc, finalPrice));
 return finalPrice;
 }
}

测试

package designpattern.strategy.now;
import designpattern.strategy.now.discount.impl.*;
public class Test {
 public static void main(String[] args) {
 BuyGoods buyGoods1 = new BuyGoods("Java编程思想", 99.00, new
Discount85());
 buyGoods1.calculate();
 BuyGoods buyGoods2 = new BuyGoods("罗技⿏标", 66, new Discount6());
 buyGoods2.calculate();
 BuyGoods buyGoods3 = new BuyGoods("苹果笔记本", 15000.00, new
Return5());
 buyGoods3.calculate();
 BuyGoods buyGoods4 = new BuyGoods("佳能相机", 1900, new
NoDiscount());
 buyGoods4.calculate();
 }
}

重构后:
增加新的优惠⽅案时只需要继承抽象策略类即可,修改优惠⽅案时不需要修改BuyGoods类
源码;
代码复⽤也变得简单,直接复⽤某⼀个具体策略类即可;
BuyGoods类的calculate变得简洁,没有了原本的if分⽀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时小浅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值