阅读量:0
一.策略模式定义
1.Context封装角色
它也叫上下文,起承上启下的封装作用,屏蔽高层模块对策略、算法的直接访问,封装肯存在变化。
2.Strategy抽象策略角色
策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
3.ConcreteStrategy具体策略角色
实现抽象策略中的操作,改了包含具体的实现等算法或业务特色。
二. 示例
1.抽象的策略角色
/** * 抽象策略角色 */ public interface Strategy { /** * 策略模式算法或者业务特色的控制 */ void dosomething(); }
2.具体策略角色
public class ConcreteStrateg1 implements Strategy{ @Override public void dosomething() { //TODO 实现策略或者具体的业务逻辑 } } public class ConcreteStrateg2 implements Strategy{ @Override public void dosomething() { //TODO 实现策略或者具体的业务逻辑 } }
3.封装角色
/** * 封装角色 */ public class Context { private Strategy strategy = null; public Context(Strategy strategy) { this.strategy = strategy; } public void doAnything() { this.strategy.dosomething(); } }
4.高层模块使用
public class Client { public static void main(String[] args) { //声明一个具体的策略 Strategy strategy = new ConcreteStrateg1(); //声明上下文 Context context = new Context(strategy); //执行封装后的方法 } }
三.应用场景
1.电商平台购物车渲染
(1)定义购物车渲染枚举
/** * 购物车渲染枚举 */ 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)抽象购物车渲染步骤策略
/** * 购物车渲染 */ public interface CartRenderStep { /** * 渲染价格步骤 * * @return 渲染枚举 */ RenderStepEnums step(); /** * 渲染一笔交易 * * @param tradeDTO 交易DTO */ void render(Object tradeDTO); }
(3)实现购物车渲染的业务逻辑
/** * 购物车渲染,将购物车中的各个商品,拆分到每个商家,形成购物车VO */ public class CartPriceRender implements CartRenderStep { @Override public RenderStepEnums step() { return RenderStepEnums.CART_PRICE; } @Override public void render(Object tradeDTO) { //TODO 计算商品价格等 } }
/** * 交易流水号生成 */ public class CartSnRender implements CartRenderStep { @Override public RenderStepEnums step() { return RenderStepEnums.CART_SN; } @Override public void render(Object tradeDTO) { //生成流水号等等 } }
/** * sku 运费计算 * */ public class SkuFreightRender implements CartRenderStep { @Override public RenderStepEnums step() { return RenderStepEnums.SKU_FREIGHT; } @Override public void render(TradeDTO tradeDTO) { //收货地址问题处理、校验等 //运费模板选择等 //选择物流的时候计算价格 } }
(4)封装购物车渲染策略
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)根据业务场景选择策略
/** * 购物车渲染 步骤声明 * */ 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)高层业务模块使用
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); } }