设计模式之策略模式

在代码逻辑中,如果需要根据不同的条件执行不同的代码逻辑,我们最容易想到的就是使用if-else结构去进行判断,代码结构如下图所示:

if (condition1) {
	// todo
} else if (condition2) {
	// todo
} else if (condition3) {
	// todo
} else if (condition4) {
	// todo
}

在后续业务迭代的过程当中,如果需要增加新的逻辑判断和处理,我们就需要在原代码的基础上再增加新的分支,这样违背了面向对象设计中的开闭原则(Open-Close Principle),即对扩展开放,对修改关闭。面对这种分支判断较多的场景,在系统设计时我们可以引入设计模式中的策略模式,其类图关系如下所示:

策略模式的设计中包含三个角色:

  1. 抽象策略角色:一般定义成一个接口或者抽象类;
  2. 具体策略角色:封装具体的算法逻辑,即具体分支逻辑的代码实现;
  3. 环境角色:有时也称上下文角色,是具体策略的持有者;

下面以SpringBoot项目为例来说明策略模式的编写:

抽象策略类:

public interface ModuleAssembleStrategy {

    /**
     * Description: 填充模板信息
     */
    List<Map<String, Object>> fillModuleInfo(String moduleTemplateValue);
}

具体的策略实现类:

@Service(value = "todayModuleStrategy")
public class TodayModuleStrategy implements ModuleAssembleStrategy {

    @Autowired
    private RemoteCallService remoteCallService;

    @Override
    public List<Map<String, Object>> fillModuleInfo(String moduleTemplateValue) {
        // todo   
    }
}

@Service(value = "hotModuleStrategy")
public class HotModuleStrategy implements ModuleAssembleStrategy {

    @Autowired
    private RemoteCallService remoteCallService;

    @Override
    public List<Map<String, Object>> fillModuleInfo(String moduleTemplateValue) {
        // todo
    }
}

@Service(value = "masterModuleStrategy")
public class MasterModuleStrategy implements ModuleAssembleStrategy {

    @Autowired
    private RemoteCallService remoteCallService;

    @Override
    public List<Map<String, Object>> fillModuleInfo(String moduleTemplateValue) {
        // todo
    }
}

上下文环境角色:

public class ModuleAssembleContext {

    private ModuleAssembleStrategy moduleAssembleStrategy;

    public ModuleAssembleContext(ModuleAssembleStrategy moduleAssembleStrategy) {
        this.moduleAssembleStrategy = moduleAssembleStrategy;
    }

    public List<Map<String, Object>> executeStrategy(String moduleTemplateValue) {
        return moduleAssembleStrategy.fillModuleInfo(moduleTemplateValue);
    }
}

在service层的具体使用:

@Service
public class ModuleAssembleServiceImpl implements ModuleAssembleService {
    
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ModuleConfigProps moduleConfigProps;

    @Override
    public List<Map<String, Object>> fillModuleIfno(Integer moduleId, String moduleTemplateValue) {
        // 通过反射获取具体策略类的实例bean
        String fieldName = "module" + moduleId;
        String firstLetter = fieldName.substring(0, 1).toUpperCase();
        String getter = "get" + firstLetter + fieldName.substring(1);
        Method method = moduleConfigProps.getClass().getMethod(getter, new Class[] {});
        String beanName = (String) method.invoke(moduleConfigProps, new Object[] {});
        ModuleAssembleStrategy moduleAssembleStrategy = applicationContext.getBean(beanName);
        ModuleAssembleContext moduleAssembleContext = new ModuleAssembleContext(moduleAssembleStrategy);
        return moduleAssembleContext.executeStrategy(moduleTemplateValue);
    }
}

具体的配置类如下:

@Data
@Component
@ConfigurationProperties(prefix = "custom.module")
public class ModuleConfigProps {
    private String module1;
    private String module2;
    private String module3;
}

配置文件application.yml如下:

custom:
    module:
        module1: todayModuleStrategy
        module2: hotModuleStrategy
        module3: masterModuleStrategy

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值