设计模式[13]-策略模式-Strategy Pattern

1.策略模式简介

策略模式(Strategy Patter)是行为型(Behavioral)设计模式,策略模式封装了一系列算法,每种算法是一种策略,可以互相切换。

策略模式的主要目的是将算法的定义和算法的使用分开,算法的定义在具体的策略类中,使用算法的上下文类针对抽象策略编程。

策略模式一共有三种角色:

  • Context(上下文类): 上下文类是使用算法策略的角色,拥有抽象策略类的引用实例,用于定义采用何种策略。

  • Strategy(抽象策略类):定义算法的接口,是所有具体策略类的父类。

  • ConcreteStrategy(具体策略类): 实现抽象策略接口,是一个具体的策略。

2. 策略模式举例

下面我们举一个卖票打折的例子,不同的客户享有不同的角色。

序号 类名 角色 说明
1 Ticket Context 上下文类,票
2 Discount Strategy 抽象策略类,折扣
3 VipDiscount ConcreteStrategy 具体策略类,VIP折扣
4 StudentDiscount ConcreteStrategy 具体策略类,学生折扣
5 StrategyMain 客户端 演示调用
设计模式[13]-策略模式-Strategy Pattern_第1张图片
Strategy Pattern

1. 环境类角色,票类。

public class Ticket {

    /**
     * 票价
     */
    private BigDecimal price;
    /**
     * 折扣
     */
    private Discount discount;

    /**
     * 获取折扣价格
     *
     * @return 折扣价格
     */
    public BigDecimal getPrice() {
        if (discount == null)
            return price;
        return discount.calculate(price);
    }

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

    public void setDiscount(Discount discount) {
        this.discount = discount;
    }
}

2.抽象策略类,折扣类

public interface Discount {

    /**
     * 折扣计算
     *
     * @param price 原价
     * @return 折后价
     */
    BigDecimal calculate(BigDecimal price);

}

3.具体策略类,VIP会员打折策略

public class VipDiscount implements Discount {

    private BigDecimal discount = BigDecimal.valueOf(0.7);

    @Override
    public BigDecimal calculate(BigDecimal price) {
        System.out.println("折扣系统:VIP买票享受7折优惠。");
        //  VIP票,打7折。
        return price.multiply(discount);
    }
}

4.具体策略类, 学生票打折策略

public class StudentDiscount implements Discount {

    private BigDecimal discount = BigDecimal.valueOf(10L);

    @Override
    public BigDecimal calculate(BigDecimal price) {
        System.out.println("折扣系统:学生买票立减10元。");
        // 学生票,优惠10块
        return price.subtract(discount);
    }
}

5.客户端

public class StrategyMain {

    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        BigDecimal originalPrice = BigDecimal.valueOf(80L);
        ticket.setPrice(originalPrice);
        System.out.println("售票系统:票价原价80元");

        System.out.println("售票系统:VIP来买票");
        Discount discount = new VipDiscount();
        ticket.setDiscount(discount);

        // 折扣价格
        BigDecimal discountedPrice = ticket.getPrice();
        System.out.println("折扣票价(元)" + discountedPrice);
    }
}

结果输出

售票系统:票价原价80元
售票系统:VIP来买票
折扣系统:VIP买票享受7折优惠。
折扣票价(元)56.0

3. 总结

策略模式实现了算法的封装与切换,达到了算法的定义和使用分离的目的;提供了管理算法族的办法,也可以灵活地增加新的算法;提供了一种可以替换继承关系的办法,避免大量使用if else。

策略模式,需要客户端知道所有的策略类,并自行确定使用哪个;系统中可能会产生大量的策略类,并且一次只能使用一个策略类。

Java AWT中就有策略模式的应用,java.awt.Container就是Context角色,java.awt.LayoutManager就是抽象策略角色。

(完)

你可能感兴趣的:(设计模式[13]-策略模式-Strategy Pattern)