简介
UML图

应用场景
- Java AWT中的LayoutManager(布局管理器)
- 系统中存在多个类,它们的区别仅在于它们的行为
- 不希望暴露复杂与算法有关的数据结构
- Java中Comparator 接口常用的 compare()方法
示例
- 商品
public class Product {
    /**
     * 产品价格
     */
    private double price;
    /**
     * 产品名称
     */
    private String productName;
    public Product(double price, String productName) {
        this.price = price;
        this.productName = productName;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
}
- 策略:活动优惠策略
public interface Strategy {
    /**
     * 计算商品价格
     *
     * @param product
     * @return
     */
    double computePrice(Product product);
}
没有活动:
public class NormalActivity implements Strategy {
    @Override
    public double computePrice(Product product) {
        return product.getPrice();
    }
}
打折活动:
public class DiscountActivity implements Strategy {
    private double discount;
    public DiscountActivity(double discount) {
        this.discount = discount;
    }
    @Override
    public double computePrice(Product product) {
        return product.getPrice() * discount;
    }
}
代金券活动:
public class VoucherActivity implements Strategy {
    /**
     * 代金券
     */
    private double voucher;
    public VoucherActivity(double voucher) {
        this.voucher = voucher;
    }
    @Override
    public double computePrice(Product product) {
        return product.getPrice() > voucher ? product.getPrice() - voucher : 0;
    }
}
- 活动上下文:选择适当的活动促销策略
public class PromotionContext {
    /**
     * 策略
     */
    private Strategy strategy;
    public PromotionContext(Strategy strategy) {
        this.strategy = strategy;
    }
    public double executeStrategy(Product product) {
        return this.strategy.computePrice(product);
    }
}
- 运行
public class Main {
    public static void main(String[] args) {
        // 创建商品
        Product phone = new Product(1999, "手机");
        // 促销策略
        PromotionContext promotionContext;
        // 原价
        promotionContext = new PromotionContext(new NormalActivity());
        System.out.println("原价:" + promotionContext.executeStrategy(phone));
        // 8折优惠
        promotionContext = new PromotionContext(new DiscountActivity(0.8));
        System.out.println("优惠价格:" + promotionContext.executeStrategy(phone));
        // 2000代金券
        promotionContext = new PromotionContext(new VoucherActivity(2000));
        System.out.println("券后价格:" + promotionContext.executeStrategy(phone));
    }
}

总结
-  优点: - 满足开闭原则,当增加具体策略时,不需要修改上下文代码
- 避免使用过多的条件判断,过多的条件判断语句不利于系统可维护性,扩展性和灵活性
 
-  缺点 - 策略类可能过多可能导致膨胀,复用性较小
 










