1.策略模式简介
策略模式(Strategy Patter)是行为型(Behavioral)设计模式,策略模式封装了一系列算法,每种算法是一种策略,可以互相切换。
策略模式的主要目的是将算法的定义和算法的使用分开,算法的定义在具体的策略类中,使用算法的上下文类针对抽象策略编程。
策略模式一共有三种角色:
-
Context(上下文类): 上下文类是使用算法策略的角色,拥有抽象策略类的引用实例,用于定义采用何种策略。
-
Strategy(抽象策略类):定义算法的接口,是所有具体策略类的父类。
-
ConcreteStrategy(具体策略类): 实现抽象策略接口,是一个具体的策略。
2. 策略模式举例
下面我们举一个卖票打折的例子,不同的客户享有不同的角色。
序号 | 类名 | 角色 | 说明 |
---|---|---|---|
1 | Ticket | Context | 上下文类,票 |
2 | Discount | Strategy | 抽象策略类,折扣 |
3 | VipDiscount | ConcreteStrategy | 具体策略类,VIP折扣 |
4 | StudentDiscount | ConcreteStrategy | 具体策略类,学生折扣 |
5 | StrategyMain | 客户端 | 演示调用 |

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就是抽象策略角色。
(完)
网友评论