设计模式之策略模式

介绍

经常写if和switch的朋友们可以考虑用策略模式替换原有写法。

策略模式允许我们定义一系列算法,将每一个算法封装起来,并使它们可以互相替换。

主要解决的问题:

  • 当存在多种算法或策略可完成同一任务时,如何避免使用大量的条件语句(如if...else或switch...case)来决定使用哪种算法,从而提高代码的可读性和可维护性。
  • 需要在运行时根据不同的条件选择不同的算法或策略。

基本结构:

  • 策略接口(Strategy Interface):定义所有支持的算法的公共接口。策略接口使得算法可以互换。
  • 具体策略类(Concrete Strategy Classes):实现了策略接口的类,每个类封装了一个具体的算法或策略。
  • 上下文(Context):使用策略的类。上下文通常持有一个策略接口的引用,可以在运行时设置这个引用以切换到不同的策略。

实现案例

假设我们现在要处理一批文件,文件类型包括ppt、doc、xlsx等,需要根据传入文件类型不同调用不同的处理方法。

常规思路,if else或者switch,这两种都可以实现,但是有一个很明显的缺点,如果再增加一种文件类型,则需要改动判断逻辑,这不符合六大设计原则之开闭原则(一个软件实体应当对扩展开放,对修改关闭)

此时我们可以选择策略模式来替代if或switch模式,具体设计如下

策略接口

 

java

复制代码

public interface OfficeStrategy { /** * 文件处理策略 * * @param officeParam 入参 */ void handlerOffice(OfficeParam officeParam); }

策略实现类

 

java

复制代码

@Component public class DocOfficeStrategy implements OfficeStrategy { @Override public void handlerOffice(OfficeParam officeParam) { System.out.println("开始处理"+ officeParam.getFileType()); } } @Component public class PptOfficeStrategy implements OfficeStrategy{ @Override public void handlerOffice(OfficeParam officeParam) { System.out.println("开始处理"+ officeParam.getFileType()); } } @Component public class XlsxOfficeStrategy implements OfficeStrategy { @Override public void handlerOffice(OfficeParam officeParam) { System.out.println("开始处理"+ officeParam.getFileType()); } }

策略上下文

 

java

复制代码

@Component public class OfficeStrategyContext { @Autowired private final Map<String, OfficeStrategy> officeTypeStrategyMap = new ConcurrentHashMap<>(); public OfficeStrategy getStrategy(String flag) { return this.officeTypeStrategyMap.get(String.format("%sOfficeStrategy", flag)); } }

注意这里的细节,我们通过spring管理策略实现类,因此在OfficeStrategyContext中通过spring ioc机制注入所有策略类的实现,根据传入的策略类型,匹配相应的策略实现。

通过这种实现方式,如果需要处理新的业务类型,创建新的OfficeStrategy实现类,并且通过spring 管理bean,还会自动将新的实现类注入到officeTypeStrategyMap中,这样就避免if和switch方式中,新加一种业务类型就需要扩展条件判断的弊端,做到了对扩展开放,对修改关闭。

测试

我们在springboot项目中,使用junit测试策略类的加载和获取

 

java

复制代码

@ActiveProfiles("dev") @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest @Slf4j public class OfficeStrategyHandlerTest { @Autowired private OfficeStrategyContext officeStrategyContext; @Test public void testOfficeStrategy() { String fileType = "doc"; OfficeStrategy officeStrategy = officeStrategyContext.getStrategy(fileType); OfficeParam officeParam = new OfficeParam(); officeParam.setFileType(fileType); officeParam.setFilePath("test.doc"); officeStrategy.handlerOffice(officeParam); } }

优缺点

优点

算法的封装与复用:每个具体策略类封装了一个算法,易于理解和复用。 扩展性良好:新增策略不需要修改原有代码,符合开闭原则。 简化了单元测试:每个策略都可以独立测试,无需依赖其他策略。 提高了代码的灵活性和可读性:消除了条件语句,使得代码更加清晰。

缺点

  • 类数量增多:每个具体策略都需要一个独立的类,如果策略较多,将导致类的数量增加。

应用场景

当有多个相似的行为,只在具体行为上有所不同,可以使用策略模式。 需要动态地在几种算法中切换的情况。 避免使用多重条件选择语句(如if...else或switch...case)来决定使用哪个算法或策略。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值