释义:
策略模式是一种行为设计模式,它允许在运行时根据不同的情况来选择不同的策略。
这种模式支持开闭原则,在不修改现有代码的前提下,动态的添加、删除、替换算法。
组成部分:
策略接口(Strategy):它是一个接口,具体的策略实现类去实现这个接口,就可以提供不同的实现方式。
策略环境(Context):可以根据需要来修改策略,或者定义一个工厂类
策略实现类(ConcreteStrategy):以Strategy接口实现某具体算法
代码实现步骤:
1、定义Strategy接口(Strategy)
package com.example.strategy.service;
import com.example.strategy.entity.ResourcesEntity;
/**
* 获取资源信息策略接口
*
*/
public interface ResourcesStrategy {
/*
* 获取对应资源信息
* 专家、队伍、装备
* */
ResourcesEntity getResourcesData(String type);
}
2、实体类、常量类定义(entity、constant)
//返回实体类
package com.example.strategy.entity;
import lombok.Data;
@Data
public class ResourcesEntity {
private String name;
private String lat;
private String lng;
private String resourcesType;
}
//常量类
package com.example.strategy.constant;
public class ResourcesConstant {
public static final String EXPERT = "expert";
public static final String EQUIP = "equip";
public static final String MATERIALS = "materials";
public static final String TEAM = "team";
}
3、具体的策略实现类(EquipStrategy、ExpertStrategy、TeamStrategy)
//装备策略实现类
package com.example.strategy;
import com.example.strategy.constant.ResourcesConstant;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.stereotype.Component;
@Component(ResourcesConstant.EQUIP)
public class EquipStrategy implements ResourcesStrategy {
@Override
public ResourcesEntity getResourcesData(String type) {
ResourcesEntity resources = new ResourcesEntity();
resources.setResourcesType(ResourcesEnum.EQUIP.id);
resources.setName("装备");
resources.setLng("");
resources.setLat("");
return resources;
}
}
//专家策略实现类
package com.example.strategy;
import com.example.strategy.constant.ResourcesConstant;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.stereotype.Component;
@Component(ResourcesConstant.EXPERT)
public class ExpertStrategy implements ResourcesStrategy {
@Override
public ResourcesEntity getResourcesData(String type) {
ResourcesEntity resources = new ResourcesEntity();
resources.setResourcesType(ResourcesEnum.EXPERT.id);
resources.setName("李安心专家");
resources.setLng("");
resources.setLat("");
return resources;
}
}
//队伍策略实现类
package com.example.strategy;
import com.example.strategy.constant.ResourcesConstant;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.stereotype.Component;
@Component(ResourcesConstant.TEAM)
public class TeamStrategy implements ResourcesStrategy {
@Override
public ResourcesEntity getResourcesData(String type) {
ResourcesEntity resources = new ResourcesEntity();
resources.setResourcesType(ResourcesEnum.TEAM.id);
resources.setName("队伍1");
resources.setLng("");
resources.setLat("");
return resources;
}
}
4、策略环境(上下文)Context
package com.example.strategy.context;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class ResourcesStrategyContext {
/*
* 策略集合
* 注入实例名和对应实例
* */
@Autowired
private Map<String, ResourcesStrategy> resourcesStrategyMap = new ConcurrentHashMap<>();
/*
* 初始化
* */
public ResourcesStrategyContext(Map<String, ResourcesStrategy> resourcesStrategyMap){
//先进行清空处理
this.resourcesStrategyMap.clear();
//由于我们的具体策略实现业务类使用了@Component注解,所以会被spring自动扫描并且装配到容器中
resourcesStrategyMap.forEach(this.resourcesStrategyMap::put);
}
public ResourcesStrategy getResourcesStrategy(String strategy){
return resourcesStrategyMap.get(strategy);
}
}
5、功能验证
package com.example.strategy.controller;
import com.example.demo.util.StringUtils;
import com.example.strategy.context.ResourcesStrategyContext;
import com.example.strategy.entity.ResourcesEntity;
import com.example.strategy.renum.ResourcesEnum;
import com.example.strategy.service.ResourcesStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/resources")
public class ResourcesController {
@Autowired
ResourcesStrategyContext resourcesStrategyContext;
@RequestMapping("/getResourcesData")
public ResourcesEntity getResourcesData(String type){
ResourcesStrategy resourcesStrategy = resourcesStrategyContext.getResourcesStrategy(type);
ResourcesEntity resourcesData = resourcesStrategy.getResourcesData(type);
return resourcesData;
}
}
6、结果展示
7、策略模式和if-esle比较:?
1、易于拓展:不需要修改原有代码,方便的增加、删除算法。
2、提高代码可读性:不同的业务处理在不同的策略实现类中,易于理解和维护
3、避免大量的if-else语句
4、提高代码复用性