策略模式(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);
    }
}
相关推荐
越甲八千2 天前
简单工厂模式和策略模式的异同
简单工厂模式·策略模式
无奈何杨3 天前
LiteFlow决策系统的策略模式,顺序、最坏、投票、权重
策略模式·模型·规则引擎·决策
Adellle5 天前
判题机的开发(代码沙箱、三种模式、工厂模式、策略模式优化、代理模式)
java·后端·代理模式·策略模式
技术思考者6 天前
Java设计模式实战:策略模式、工厂模式、模板模式组合使用
java·设计模式·策略模式
Narutolxy6 天前
️ macOS 安装 Oracle Instant Client:详细教程与实践指南20241216
macos·oracle·策略模式
智慧城市20307 天前
78页PPT丨家居集团流程信息中心战略规划报告2020
阿里云·策略模式
xiaoduyyy8 天前
【Android】行为型设计模式—策略模式、模版方法模式、观察者模式
android·设计模式·策略模式
重生之Java开发工程师10 天前
⭐设计模式—策略模式
java·设计模式·面试·策略模式
庄小焱11 天前
设计模式——Singleton(单例)设计模式
设计模式·策略模式·系统设计
Vincent(朱志强)12 天前
设计模式详解(十):策略模式——Strategy
设计模式·策略模式