【设计模式】原来代码也可以这么优雅(策略模式)

策略模式是一种行为设计模式,通过定义抽象策略接口和多个具体策略类,实现了算法的封装和动态选择。它避免了冗长的if-else或switch分支,提高了代码的可读性和可维护性,适用于需要动态选择算法的场景。文章通过四季活动的例子,展示了如何使用策略模式来代替if-else实现,强调了其在代码组织和扩展上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 设计模式之-策略模式

策略模式结构组成

  • Strategy:抽象策略类,一般为接口或者策略类
  • ConcreteStrategy:具体算法实现策略类
  • Context:环境或者上下文类,用于统一执行具体策略

其实以上三部分用白话文来解释就是: 需要一个接口和策略进行规范和约束接口和方法,这时需要一些具体的实现算法类去继承或者实现刚刚的接口和策略,最后通过一个环境或者上下文,也可以叫做工厂根据类型进行调用具体的算法!

使用场景

  • 避免冗长的 if-else 或 switch 分支判断
  • 需要动态地在几种算法中选择一种
  • 对客户隐藏具体策略 (算法) 的实现细节,彼此完全独立,扩展其余不受影响

具体场景一般为:

  • 支付方式选择
  • 打折、满减方式选择
  • 根据类型调用不同的系统

优缺点:

优点:

  • 扩展性好
  • 符合开闭原则
  • 符合单一职责原则
  • 可读性好
  • 便于维护
  • 避免多层判断

缺点:

  • 策略过多,导致策略类
  • 对新手读代码不友好

小栗子

春夏秋冬四季需要做不同的事情来演示一下策略模式的使用方案; 需求是: 如果是春天,就要去放风筝 如果是夏天,就要去游泳 如果是秋天,就要去看枫叶 如果是冬天,就要去打雪仗 没有使用策略模式的话, 肯定就是 if-if else进行实现!

If-Else 实现

 public static void main(String[]args){
        System.out.println(todoSomeThing("冬天"));
 }
 
public static String todoSomeThing(String seasons){
        if("春天".equals(seasons)){
            return seasons+"来了!我们一起去放风筝吧!";
        }else if("夏天".equals(seasons)){
            return seasons+"来了!我们一起去游泳吧!";
        }else if("秋天".equals(seasons)){
            return seasons+"来了!我们一起去放看枫叶吧!";
        }else if("冬天".equals(seasons)){
            return seasons+"来了!我们一起去打雪仗吧!";
        }else{
            return"不知道干什么";
        }
     }

策略模式实现

抽象策略

  /**
 * 四季策略
 */
public interface SeasonsStrategy {
    /**
     * 根据季节去执行不同的方案
     * @param seasons
     * @return
     */
    String execute(String seasons);
}  

具体算法实现策略类

春天

/***
 * 春季具体实现
 */
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("spring")
public class SpringStrategy implements SeasonsStrategy{

    @Override
    public String execute(String seasons) {
        return seasons + "来了!我们一起去放风筝吧!";
    }
}

夏天

/***
 * 夏季具体实现
 */
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("summer")
public class SummerStrategy implements SeasonsStrategy{

    @Override
    public String execute(String seasons) {
        return seasons + "来了!我们一起去游泳吧!";
    }
}

秋天

/***
 * 秋季具体实现
 */
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("autumn")
public class AutumnStrategy implements SeasonsStrategy{

    @Override
    public String execute(String seasons) {
        return seasons + "来了!我们一起去放看枫叶吧!";
    }
}

冬天

/***
 * 冬季具体实现
 */
// 指定容器的名称,不指定默认为类名称首字母小写
@Component("winter")
public class WinterStrategy implements SeasonsStrategy{

    @Override
    public String execute(String seasons) {
        return seasons + "来了!我们一起去打雪仗吧!";
    }
}

环境或者上下文类

/**
 * 环境或者上下文类,用于统一执行具体策略
 */
@Component
public class SeasonsFactory {
    /**
     * Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
     */
    @Autowired
    private Map<String, SeasonsStrategy> seasonsMap;

    /**
     * 处理四季统一入口方法
     *
     * @param seasons
     * @param beanName
     * @return
     */
    public String handle(String seasons, String beanName) {
        // 根据bean的名称获取对应的算法处理类
        SeasonsStrategy seasonsStrategy = seasonsMap.get(beanName);
        String execute = seasonsStrategy.execute(seasons);
        return execute;
    }
}

测试

@RestController
public class TestController {

    @Autowired
    private SeasonsFactory seasonsFactory;

    @GetMapping("/strategyTest/{seasons}/{beanName}")
    public String strategyTest(@PathVariable("seasons") String seasons, @PathVariable("beanName") String beanName) {
        String handle = seasonsFactory.handle(seasons, beanName);
        return handle;
    }
}

文章参考:https://juejin.cn/post/7246409673565716539

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值