一.策略模式定义
1.Context封装角色
它也叫上下文,起承上启下的封装作用,屏蔽高层模块对策略、算法的直接访问,封装肯存在变化。
2.Strategy抽象策略角色
策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
3.ConcreteStrategy具体策略角色
实现抽象策略中的操作,改了包含具体的实现等算法或业务特色。
二. 示例
1.抽象的策略角色
java
/**
* 抽象策略角色
*/
public interface Strategy {
/**
* 策略模式算法或者业务特色的控制
*/
void dosomething();
}
2.具体策略角色
java
public class ConcreteStrateg1 implements Strategy{
@Override
public void dosomething() {
//TODO 实现策略或者具体的业务逻辑
}
}
public class ConcreteStrateg2 implements Strategy{
@Override
public void dosomething() {
//TODO 实现策略或者具体的业务逻辑
}
}
3.封装角色
java
/**
* 封装角色
*/
public class Context {
private Strategy strategy = null;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void doAnything() {
this.strategy.dosomething();
}
}
4.高层模块使用
java
public class Client {
public static void main(String[] args) {
//声明一个具体的策略
Strategy strategy = new ConcreteStrateg1();
//声明上下文
Context context = new Context(strategy);
//执行封装后的方法
}
}
三.应用场景
1.电商平台购物车渲染
(1)定义购物车渲染枚举
java
/**
* 购物车渲染枚举
*/
public enum RenderStepEnums {
/**
* 购物车渲染枚举
*/
CHECK_DATA("校验商品"),
CHECKED_FILTER("选择商品过滤"),
COUPON("优惠券价格渲染"),
SKU_PROMOTION("商品促销计算"),
FULL_DISCOUNT("满减计算"),
SKU_FREIGHT("运费计算"),
DISTRIBUTION("分配需要分配的促销金额"),
PLATFORM_COMMISSION("平台佣金"),
CART_PRICE("购物车金额计算"),
CART_SN("交易编号创建");
private String distribution;
public String getDistribution() {
return distribution;
}
RenderStepEnums(String distribution) {
this.distribution = distribution;
}
}
(2)抽象购物车渲染步骤策略
java
/**
* 购物车渲染
*/
public interface CartRenderStep {
/**
* 渲染价格步骤
*
* @return 渲染枚举
*/
RenderStepEnums step();
/**
* 渲染一笔交易
*
* @param tradeDTO 交易DTO
*/
void render(Object tradeDTO);
}
(3)实现购物车渲染的业务逻辑
java
/**
* 购物车渲染,将购物车中的各个商品,拆分到每个商家,形成购物车VO
*/
public class CartPriceRender implements CartRenderStep {
@Override
public RenderStepEnums step() {
return RenderStepEnums.CART_PRICE;
}
@Override
public void render(Object tradeDTO) {
//TODO 计算商品价格等
}
}
java
/**
* 交易流水号生成
*/
public class CartSnRender implements CartRenderStep {
@Override
public RenderStepEnums step() {
return RenderStepEnums.CART_SN;
}
@Override
public void render(Object tradeDTO) {
//生成流水号等等
}
}
java
/**
* sku 运费计算
*
*/
public class SkuFreightRender implements CartRenderStep {
@Override
public RenderStepEnums step() {
return RenderStepEnums.SKU_FREIGHT;
}
@Override
public void render(TradeDTO tradeDTO) {
//收货地址问题处理、校验等
//运费模板选择等
//选择物流的时候计算价格
}
}
(4)封装购物车渲染策略
java
public class RenderStepContext {
/**
* spring的直接注入列表就可以了,其他的通过构造函数等方式初始化策略
* 购物车渲染步骤
*/
//@Autowired
private List<CartRenderStep> cartRenderSteps;
public RenderStepContext() {
}
public RenderStepContext(List<CartRenderStep> cartRenderSteps) {
this.cartRenderSteps = cartRenderSteps;
}
public void renderCartBySteps(Object dto, RenderStepEnums[] renderSteps) {
for (RenderStepEnums step : renderSteps) {
for (CartRenderStep render : cartRenderSteps) {
try {
if (render.step().equals(step)) {
render.render(dto);
}
} catch (Exception e) {
throw e;
}
}
}
}
}
(5)根据业务场景选择策略
java
/**
* 购物车渲染 步骤声明
*
*/
public class RenderStepStatement {
/**
* 测试
*/
public static RenderStepEnums[] test = {
RenderStepEnums.CART_PRICE,
RenderStepEnums.CART_SN
};
/**
* 购物车购物车渲染
* 校验商品 》 满优惠渲染 》 渲染优惠 》计算价格
*/
public static RenderStepEnums[] cartRender = {
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.FULL_DISCOUNT,
RenderStepEnums.CART_PRICE};
/**
* 结算页渲染
* 过滤选择的商品 》 校验商品 》 满优惠渲染 》 渲染优惠 》
* 优惠券渲染 》 计算运费 》 计算价格
*/
public static RenderStepEnums[] checkedRender = {
RenderStepEnums.CHECKED_FILTER,
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.FULL_DISCOUNT,
RenderStepEnums.COUPON,
RenderStepEnums.SKU_FREIGHT,
RenderStepEnums.CART_PRICE,
};
/**
* 单个商品优惠,不需要渲染满减优惠
* 用于特殊场景:例如积分商品,拼团商品,虚拟商品等等
*/
public static RenderStepEnums[] checkedSingleRender = {
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.COUPON,
RenderStepEnums.SKU_FREIGHT,
RenderStepEnums.CART_PRICE
};
/**
* 交易创建前渲染
* 渲染购物车 生成SN 》分销人员佣金渲染 》平台佣金渲染
*/
public static RenderStepEnums[] singleTradeRender = {
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.SKU_FREIGHT,
RenderStepEnums.CART_PRICE,
RenderStepEnums.CART_SN,
RenderStepEnums.DISTRIBUTION,
RenderStepEnums.PLATFORM_COMMISSION
};
/**
* 交易创建前渲染
* 渲染购物车 生成SN 》分销人员佣金渲染 》平台佣金渲染
*/
public static RenderStepEnums[] pintuanTradeRender = {
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.COUPON,
RenderStepEnums.SKU_FREIGHT,
RenderStepEnums.CART_PRICE,
RenderStepEnums.CART_SN,
RenderStepEnums.DISTRIBUTION,
RenderStepEnums.PLATFORM_COMMISSION
};
/**
* 交易创建前渲染
* 渲染购物车 生成SN 》分销人员佣金渲染 》平台佣金渲染
*/
public static RenderStepEnums[] tradeRender = {
RenderStepEnums.CHECKED_FILTER,
RenderStepEnums.CHECK_DATA,
RenderStepEnums.SKU_PROMOTION,
RenderStepEnums.FULL_DISCOUNT,
RenderStepEnums.COUPON,
RenderStepEnums.SKU_FREIGHT,
RenderStepEnums.CART_PRICE,
RenderStepEnums.CART_SN,
RenderStepEnums.DISTRIBUTION,
RenderStepEnums.PLATFORM_COMMISSION
};
}
(6)高层业务模块使用
java
public class StrategyTest {
public static void main(String[] args) {
List<CartRenderStep> stepList = new ArrayList<>();
stepList.add(new CartPriceRender());
stepList.add(new CartSnRender());
RenderStepContext context = new RenderStepContext(stepList);
context.renderCartBySteps(new Object(), RenderStepStatement.test);
}
}