主要解决
使用策略模式代替 if…else 。主要解决在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。比如:处理不同类型订单问题,处理不同字典类型值问题等等。
案例
这里要实现的是根据不同的字段类型使用策略模式将字典码值替换为字典值并返回。
定义接口
public interface FieldConversionStrategy {
Map<String, Object> convertToDict(TemplateField templateFieldList, Map<String, Object> entry, Map<String, Object> map);
}
实现类
radio类型
@Component
public class RadioStrategy implements FieldConversionStrategy{
@Override
public Map<String, Object> convertToDict(TemplateField templateFieldList, Map<String, Object> entry, Map<String, Object> map) {
entry.forEach((k,v)->{
map.put(k,findLabelInOptions(templateFieldList, (Serializable) v));
});
return map;
}
public String findLabelInOptions(TemplateField templateField, Serializable value) {
return templateField.getOptions().stream().filter(o -> o.getValue().equals(value))
.map(TemplateFieldOptions::getLabel).findFirst().orElse(Strings.EMPTY);
}
}
其他类型;别的其他类型如上实现接口FieldConversionStrategy 即可
@Component
public class OtherStrategy implements FieldConversionStrategy {
@Override
public Map<String, Object> convertToDict(TemplateField templateFieldList, Map<String, Object> entry, Map<String, Object> map) {
entry.forEach((k,v)->{
map.put(k,v);
});
return map;
}
}
枚举类
这里的枚举类是为了处理根据不同的类型走不同的转换策略;
public enum FieldStrategyEnum {
RADIO("radio", "radio"),
CHECKBOX("checkbox", "checkbox"),
SELECT("select", "select"),
ZDYSELECT("zdyselect","zdyselect"),
TREE_SELECT("treeSelect", "treeselect"),
TTEXTAREA("textarea","textarea"),
OTHER("other", "other");
private String FieldType;
private String className;
private FieldStrategyEnum(String fieldType, String className) {
this.FieldType = fieldType;
this.className = className;
}
public String getFieldType() {
return FieldType;
}
public String getClassName() {
return className;
}
public static FieldStrategyEnum getByFieldType(String fieldType) {
for (FieldStrategyEnum fieldStrategyEnum : FieldStrategyEnum.values()) {
if (fieldStrategyEnum.getFieldType().equals(fieldType)) {
return fieldStrategyEnum;
}
}
return FieldStrategyEnum.OTHER;
}
public static boolean contains(String fieldType) {
for (FieldStrategyEnum d : FieldStrategyEnum.values()) {
if (d.getFieldType().equals(fieldType)) {
return true;
}
}
return false;
}
}
策略
@Service
public class ResourceTypeService {
private Map<String, Function<String, FieldConversionStrategy>> res = new HashMap<>();
@Autowired
private Map<String, FieldConversionStrategy> strategyMap;
/**
* 初始化 业务逻辑分派Map 其中value 存放的是 lambda表达式
*/
@PostConstruct
public void resourceInit() {
strategyMap.entrySet().forEach(e -> {
String key = e.getKey().replace("Strategy", "").toLowerCase();
res.put(key, type -> e.getValue());
});
}
public FieldConversionStrategy getResourceType(String key) throws Exception {
Function<String, FieldConversionStrategy> result = res.get(key);
String type = "";
if (result != null) {
// 返回对象
return result.apply(type);
}
throw new Exception("没有相应的策略");
}
}
调用
这里就是根据不同的字段类型获取到对应的转换方法。
private Map<String, Object> parseLabel(TemplateField templateField, Map<String, Object> entry, Map<String, Object> map) throws Exception {
String strategyName = FieldStrategyEnum.getByFieldType(templateField.getType()).getClassName();
FieldConversionStrategy service = strategy.getResourceType(strategyName);
// 转换方法
return service.convertToDict(templateField,entry,map);
}