策略模式(Strategy),就是?个问题有多种解决?案,选择其中的?种使?,这种情况下我们使?策略模式来实现灵活地选择,也能够?便地增加新的解决?案。?如做数学题,?个问题的解法可能有多种;再?如商场的打折促销活动,打折?案也有很多种,有些商品是不参与折扣活动要按照原价销售,有些商品打8.5折,有些打6折,有些是返现5元等
策略(Strategy)定义所有?持算法的公共接?。 Context 使?这个接?来调?某 ConcreteStrategy 定义的算法。策略实现(ConcreteStrategy)实现了Strategy 接?的具体算法
上下?(Context)维护?个 Strategy 对象的引?,??个 ConcreteStrategy 对象来装配,可定义?个接??法让 Strategy 访问它的数据
示例
假如现在有?个商场优惠活动,有的商品原价售卖,有的商品打8.5折,有的商品打6折,有的返现5元
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; } }
测试
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抽象?法
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 ?法中实现具体的打折?案(算法)
public class Discount85 extends AbstractDiscount { public Discount85() { super("该商品可享受8.5折优惠"); } @Override public double discount(double price) { finalPrice = price * 0.85; return finalPrice; } } public class Discount6 extends AbstractDiscount { public Discount6() { super("该商品可享受6折优惠"); } @Override public double discount(double price) { finalPrice = price * 0.6; return finalPrice; } } public class Return5 extends AbstractDiscount { public Return5() { super("该商品可返现5元"); } @Override public double discount(double price) { this.finalPrice = price >= 5 ? price - 5 : 0; return finalPrice; } } public class NoDiscount extends AbstractDiscount { public NoDiscount() { super("对不起,该商品不参与优惠活动"); } @Override public double discount(double price) { finalPrice = price; return finalPrice; } }
类 BuyGoods,维护了?个 AbstractDiscount 引?
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; } }
测试
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分?;
原文:https://www.cnblogs.com/brook0366/p/13744645.html