设计模式(第十六式:策略模式)

概念:
  策略模式:Define a family of algorithms, encapsulate each one, and make them interchangeable. 定义一组算法,封装每个算法,并使他们之间可以互相转换。

实现:
  抽象的策略类

public abstract class AbstractDiscount {
    public AbstractDiscount(Integer num, Double price) {
        this.num = num;
        this.price = BigDecimal.valueOf(price);
    }

    private Integer num;
    private BigDecimal price;

    public abstract BigDecimal discount();

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}


  具体的策略实现类

public class NoDiscount extends AbstractDiscount {

    public NoDiscount(Integer num, Double price) {
        super(num, price);
    }

    /**
     * 免费赠品
     * @return
     */
    @Override
    public BigDecimal discount() {
        return BigDecimal.valueOf(0);
    }
}
public class FixDiscount extends AbstractDiscount {
    public FixDiscount(Integer num, Double price) {
        super(num, price);
    }

    /**
     * 原价商品
     * @return
     */
    @Override
    public BigDecimal discount() {
        return getPrice().multiply((BigDecimal.valueOf(getNum() * 1)));
    }
}
public class EighthFoldDiscount extends AbstractDiscount {

    public EighthFoldDiscount(Integer num, Double price) {
        super(num, price);
    }

    /**
     * 八五折
     * @return
     */
    @Override
    public BigDecimal discount() {
        return getPrice().multiply(BigDecimal.valueOf(getNum() * 0.85));
    }
}


  总的调用类

public class Calculate {
    private AbstractDiscount discount;

    public Calculate(AbstractDiscount discount){
        this.discount = discount;
    }

    public BigDecimal calculatePrice(){
        return discount.discount();
    }
}


测试及结果:

@Test
public void strategyTest() {
    Calculate calculateNo = new Calculate(new NoDiscount(20, 21.5));
    System.out.println("免费书籍计算价格:" + calculateNo.calculatePrice());
    Calculate calculateFix = new Calculate(new FixDiscount(20, 21.5));
    System.out.println("原价书籍计算价格:" + calculateFix.calculatePrice());
    Calculate calculateEighthFold = new Calculate(new EighthFoldDiscount(20, 21.5));
    System.out.println("八五折书籍计算价格:" + calculateEighthFold.calculatePrice());

}


    免费书籍计算价格:0
    原价书籍计算价格:430.0
    八五折书籍计算价格:365.50

分析:
  1.策略模式利于扩展,容易形成统一算法的家族簇。当然这样就可能会出现过于臃肿,比如0.01,0.02到1这就需要写100个扩展,所以要具体情况具体分析。
  2.策略模式使用继承的方式处理算法或者类行为,所以不利于每个算法的独立扩展。
  3.使用策略模式能使控制权交由上层或客户端处理,具体选择哪个策略是上一步传入,使代理的灵活性提高。
  4.常见的,一般在算法加密上用的比较对,如果我们对一串字符串加密,客户端只要指明使用什么加密算法加密,程序会根据选择的策略进行加密。提高了整体的代码封装。

原文地址:https://www.cnblogs.com/ben-mario/p/11133384.html