前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

作者头像
韩曙亮
发布2023-03-29 15:30:26
1K0
发布2023-03-29 15:30:26
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、策略模式简介


策略模式 : 定义了 算法家族 , 分别 封装起来 , 让它们之间 , 可以 相互替换 , 此模式 让 算法的变化 不会影响到 使用算法的用户 ;

将 不同的算法 , 封装到 不同的类 中 , 让它们之间可以 相互替换 , 使用算法的用户 即 应用层 , 感知不到 算法已经被替换了 ;

实际的业务场景 :

  • 不同业务逻辑 : 商品促销 , 促销策略 , 不同的促销策略算法 , 封装到不同的类中 ;
  • 代码优化 : 如果代码中 , 有大量的 if … else … 代码 , 可以通过策略模式 , 替换相关逻辑 ;

策略模式类型 : 行为型 ;

二、策略模式适用场景


策略模式适用场景 :

  • 行为切换 : 系统有 很多类 , 这些类的区别仅仅在于它们的 行为不同 ; 使用策略模式 , 可以 动态地 让 用户对象 在这些行为中, 选择一个行为 ; 将对象的 不同的行为 , 封装到 不同的类 中 , 每个行为对应一种策略 ;
  • 算法选择 : 系统中需要 动态地 在 几种算法 中 选择一种 ; 算法 就是 策略 , 其中封装了一系列的业务逻辑及计算方式 ; 如 : 计算方式 , 给定两个数字 ; 使用加法策略 , 将两个数相加 ; 使用乘法策略 , 将两个数相乘 ;

三、策略模式优缺点


策略模式优点 :

  • 开闭原则 : 策略模式 提供了 对 开闭原则 的支持 , 可以在不修改原有系统的基础上 , 选择不同的行为 , 也可以 额外扩展其它行为 ;
  • 避免代码冗余 : 可以 避免使用多重条件判定语句 ; 可以避免出现大量的 if … else … 语句 , switch 语句等 ;
  • 安全保密 : 策略模式可以 提高算法的 保密性 和 安全性 ; 在终端使用策略时 , 只需要知道策略的作用即可 , 不需要知道策略时如何实现的 ;

策略模式缺点 :

  • 策略类选择 : 客户端 必须 知道所有的 策略类 , 并且自行决定 使用哪个策略类 ;
  • 增加复杂性 : 如果系统很复杂 , 会 产生很多策略类 ;

四、策略模式与其它设计模式


策略模式与工厂模式 :

  • 工厂模式 : 接受指令 , 创建出符合要求的具体对象 ; 工厂模式 分为 工厂方法模式 和 抽象工厂模式 , 工厂模式 是 创建型的设计模式 , 策略模式 是 行为型的设计模式 ;
  • 策略模式 : 接受创建好的实例对象 , 从而实现不同的行为 ;

策略模式与状态模式 :

  • 策略模式 : 使用策略模式时 , 客户端 需要知道使用哪个策略 ;
  • 状态模式 : 使用状态模式时 , 客户端 不需要知道具体的状态 , 这些状态之间会自动转换 ;

设计模式选择 :

  • 状态模式 : 如果系统中 , 某个对象存在多种状态 , 在不同状态下 , 行为有差异的话 , 使用状态模式 ;
  • 策略模式 : 如果系统中 , 某个类的某个行为 , 有多种实现方式 , 使用策略模式 ;

策略模式 一般不是独立使用的 , 可能需要结合单例 , 工厂模式 , 享元模式 等多个设计模式 , 一起实现业务逻辑 ;

如果遇到大量的 if … else … 可以考虑是否可以抽象 对象 以及 行为 , 将其封装成策略模式 ;

如果一个对象的行为经常变化 , 扩展性要求比较高 , 也可以考虑使用策略模式 ;

五、策略模式代码示例


业务场景 :

商场促销活动 : 促销是商品的一个行为 , 促销行为 , 设置多个促销行为 , 将其封装到类中 ;

1、促销策略接口

代码语言:javascript
复制
package strategy;

/**
 * 促销策略接口
 *      所有的促销策略 , 都要实现该接口
 */
public interface PromotionStrategy {
    /**
     * 促销活动
     */
    void doPromotion();
}

2、满减促销策略

代码语言:javascript
复制
package strategy;

/**
 * 满减促销策略
 *      满 100 减 20
 */
public class ManJianPromotionStrategy implements PromotionStrategy {

    @Override
    public void doPromotion() {
        System.out.println("满减促销 , 满 100 减 20");
    }
}

3、返现促销策略

代码语言:javascript
复制
package strategy;

/**
 * 返现促销策略
 *      购买后返优惠券
 */
public class FanXianPromotionStrategy implements PromotionStrategy {

    @Override
    public void doPromotion() {
        System.out.println("返现促销 , 返优惠券 10 元");
    }
}

4、空促销策略

代码语言:javascript
复制
package strategy;

/**
 * 空的促销策略
 *      为了防止空指针
 */
public class EmptyPromotionStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("原价出售");
    }
}

5、促销策略工厂

代码语言:javascript
复制
package strategy;

import java.util.HashMap;

/**
 * 促销策略工厂
 */
public class PromotionStrategyFactory {
    private static HashMap<String, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN, new ManJianPromotionStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN, new FanXianPromotionStrategy());
    }

    /**
     * 构造函数不能被外界访问
     */
    private PromotionStrategyFactory() {
    }

    /**
     * 根据传入的键值获取相应的促销策略
     * @param promotionKey
     * @return
     */
    public static PromotionStrategy getPromotionStrategy(String promotionKey) {
        PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
        return promotionStrategy != null ? promotionStrategy : new EmptyPromotionStrategy();
    }

    /**
     * 使用这种方式声明常量 , 可以起到逻辑上分组的作用
     */
    public interface PromotionKey {
        String MANJIAN = "ManJian";
        String FANXIAN = "FanXian";
    }
}

6、促销活动

代码语言:javascript
复制
package strategy;

/**
 * 促销活动
 */
public class PromotionActivity {
    /**
     * 促销策略 , 通过构造器注入
     */
    private PromotionStrategy promotionStrategy;

    public PromotionActivity(PromotionStrategy promotionStrategy) {
        this.promotionStrategy = promotionStrategy;
    }

    /**
     * 执行促销策略
     */
    public void executePromotionStrategy() {
        this.promotionStrategy.doPromotion();
    }
}

7、测试类

代码语言:javascript
复制
package strategy;

public class Main {
    public static void main(String[] args) {
        // 获取促销策略
        PromotionStrategy promotionStrategy = PromotionStrategyFactory.
                getPromotionStrategy(PromotionStrategyFactory.PromotionKey.FANXIAN);
        // 创建促销活动 , 并执行促销策略
        PromotionActivity promotionActivity = new PromotionActivity(promotionStrategy);
        // 执行促销策略
        promotionActivity.executePromotionStrategy();
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、策略模式简介
  • 二、策略模式适用场景
  • 三、策略模式优缺点
  • 四、策略模式与其它设计模式
  • 五、策略模式代码示例
    • 1、促销策略接口
      • 2、满减促销策略
        • 3、返现促销策略
          • 4、空促销策略
            • 5、促销策略工厂
              • 6、促销活动
                • 7、测试类
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档