首页 > 其他 > 详细

设计模式之策略模式

时间:2020-10-02 22:37:06      阅读:37      评论:0      收藏:0      [点我收藏+]

策略模式

策略模式(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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!