FSA全栈行动 FSA全栈行动
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr

公众号:FSA全栈行动

记录学习过程中的知识
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr
  • DesignPattern - 设计原则与设计模式初探
  • DesignPattern - 单例模式【创建型】
  • DesignPattern - 工厂模式【创建型】
  • DesignPattern - 原型模式【创建型】
  • DesignPattern - 建造者模式【创建型】
  • DesignPattern - 适配器模式【结构型】
  • DesignPattern - 桥接模式【结构型】
  • DesignPattern - 组合模式【结构型】
  • DesignPattern - 装饰器模式【结构型】
  • DesignPattern - 代理模式【结构型】
  • DesignPattern - 外观模式【结构型】
  • DesignPattern - 享元模式【结构型】
  • DesignPattern - 策略模式【行为型】
    • 一、策略模式介绍
    • 二、策略模式代码实现
  • DesignPattern - 模板方法模式【行为型】
  • DesignPattern - 观察者模式【行为型】
  • DesignPattern - 责任链模式【行为型】
  • DesignPattern - 命令模式【行为型】
  • DesignPattern - 迭代器模式【行为型】
  • DesignPattern - 备忘录模式【行为型】
  • DesignPattern - 状态模式【行为型】
  • 《深入浅出设计模式Java版》
FullStackAction
2021-09-09
目录

DesignPattern - 策略模式【行为型】

欢迎关注微信公众号:[FSA全栈行动 👋]

# 一、策略模式介绍

策略模式(Strategy Pattern)定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换

  • 核心组成

    • Context 上下文:屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化
    • Strategy 策略角色:抽象策略角色,是对策略、算法家族的抽象,定义每个策略或算法必须具有的方法和属性
    • ConcreteStrategy 具体策略角色:用于实现抽象策略中的操作,即实现具体的算法
  • 应用场景

    • 外出旅游,选择骑自行车、坐汽车、飞机等,每一种旅行方式都是一个策略
    • Java AWT 中的 LayoutManager(布局管理器)
    • 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么可以使用策略模式
    • 不希望暴露复杂的、与算法有关的数据结构,那么可以使用策略模式来封装算法
  • 优点

    • 满足开闭原则,当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例
    • 避免使用多重条件判断,如果不同策略模式可能会使用多重条件语句,不利于维护,和工厂模式搭配使用可以很好地消除 if-else 代码的多层嵌套(工厂模式主要是根据参数,获取不同的策略)
  • 缺点

    • 策略类数量会增多,每个策略都是一个类,复用的可能性很小
    • 对外暴露了类所有的行为和算法,行为过多导致策略类膨胀

补充:JDK 中的 Collections#sort(list, comparator) 就是策略模式,比较逻辑由外部传入决定。

# 二、策略模式代码实现

以电商促销为例,一件商品,平时 800 元,赶上国庆促销,有 3 种折扣方式供用户选择:

  • 不使用任何折扣
  • 使用 8 折折扣
  • 使用优惠券折扣

创建商品订单类:

/**
 * 商品订单类
 *
 * @author GitLqr
 */
public class ProductOrder {

	private float oldPrice;
	private int userId;
	private int productId;

	public ProductOrder(float oldPrice, int userId, int productId) {
		super();
		this.oldPrice = oldPrice;
		this.userId = userId;
		this.productId = productId;
	}

	... settter & getter ...
}

创建抽象策略类,当前策略的目的就是计算出折扣后的价格:

/**
 * 抽象策略角色:活动策略
 *
 * @author GitLqr
 */
public abstract class ActivityStrategy {

	/**
	 * 计算订单价格
	 */
	public abstract double computePrice(ProductOrder productOrder);
}

创建具体策略类,对应上面的 3 种折扣方式:

/**
 * 具体策略:没有活动
 *
 * @author GitLqr
 */
public class NormalActivityStrategy extends ActivityStrategy {

	@Override
	public double computePrice(ProductOrder productOrder) {
		return productOrder.getOldPrice();
	}
}

/**
 * 具体策略:打折活动
 *
 * @author GitLqr
 */
public class DiscountActivityStrategy extends ActivityStrategy {

	private float rate; // 折扣

	public DiscountActivityStrategy(float rate) {
		super();
		this.rate = rate;
	}

	@Override
	public double computePrice(ProductOrder productOrder) {
		return productOrder.getOldPrice() * rate;
	}
}

/**
 * 具体策略:优惠券抵扣活动
 *
 * @author GitLqr
 */
public class VoucherActivityStrategy extends ActivityStrategy {

	private float voucher;

	public VoucherActivityStrategy(float voucher) {
		super();
		this.voucher = voucher;
	}

	@Override
	public double computePrice(ProductOrder productOrder) {
		if (productOrder.getOldPrice() > voucher) {
			return productOrder.getOldPrice() - voucher;
		} else {
			return 0;
		}
	}
}

创建上下文类:

说明:对外屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化

/**
 * 上下文:促销上下文
 *
 * @author GitLqr
 */
public class PromotionContext {
	// 持有具体策略
	private ActivityStrategy activityStrategy;

	public PromotionContext(ActivityStrategy activityStrategy) {
		super();
		this.activityStrategy = activityStrategy;
	}

	// 直接使用具体策略进行计算
	public double executeStrategy(ProductOrder productOrder) {
		return activityStrategy.computePrice(productOrder);
	}
}

使用:

public static void main(String[] args) {

    ProductOrder productOrder = new ProductOrder(800, 9527, 1001);
    PromotionContext promotionContext;
    double finalPrice;

    // 没活动
    promotionContext = new PromotionContext(new NormalActivityStrategy());
    finalPrice = promotionContext.executeStrategy(productOrder);
    System.out.println("正常价:" + finalPrice);

    // 打折活动
    promotionContext = new PromotionContext(new DiscountActivityStrategy(0.8f));
    finalPrice = promotionContext.executeStrategy(productOrder);
    System.out.println("折扣价:" + finalPrice);

    // 使用优惠券抵扣
    promotionContext = new PromotionContext(new VoucherActivityStrategy(100));
    finalPrice = promotionContext.executeStrategy(productOrder);
    System.out.println("使用优惠券抵扣价:" + finalPrice);
}
#设计模式#策略模式
DesignPattern - 享元模式【结构型】
DesignPattern - 模板方法模式【行为型】

← DesignPattern - 享元模式【结构型】 DesignPattern - 模板方法模式【行为型】→

最近更新
01
Flutter - Xcode16 还原编译速度
04-05
02
AI - 免费的 Cursor 平替方案
03-30
03
Android - 2025年安卓真的闭源了吗
03-28
更多文章>
Theme by Vdoing | Copyright © 2020-2025 FSA全栈行动
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×