策略模式(Strategy Pattern)

一.策略模式定义

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);
    }
}
相关推荐
都说名字长不会被发现11 小时前
模版方法 + 策略模式在库存增加/扣减场景下的应用
策略模式·模板方法模式·宏命令·策略聚合·库存设计
默|笙12 小时前
【Linux】进程概念与控制(2)_进程控制
java·linux·策略模式
枫叶林FYL2 天前
Agent/Teakenote 系统(Swarm 架构)深度技术报告
架构·策略模式
苏渡苇3 天前
枚举的高级用法——用枚举实现策略模式和状态机
java·单例模式·策略模式·枚举·状态机·enum
harder3215 天前
Swift 面向协议编程的 RMP 模式
开发语言·ios·mvc·swift·策略模式
skywalk81635 天前
esxi8 虚拟机中怎么安装mac os(纯AI回答,未实践)
策略模式·esxi
廖圣平6 天前
从零开始,福袋直播间脚本研究【八】《策略模式》
开发语言·python·bash·策略模式
爱学习 爱分享9 天前
简单工厂模式和策略模式的区别
简单工厂模式·策略模式
xcntime12 天前
Python中print函数如何实现不换行输出?
策略模式
青春易逝丶13 天前
策略模式
java·开发语言·策略模式