spring增强策略模式-改造后

This commit is contained in:
fujiayang
2022-01-26 10:01:33 +08:00
parent 9347b5f4e4
commit f226ad20d1
13 changed files with 377 additions and 18 deletions

View File

@@ -148,6 +148,13 @@
<version>8.0.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
</dependencies>
<build>

View File

@@ -0,0 +1,109 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.apache.commons.lang3.StringUtils;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.*;
import java.util.ArrayList;
import java.util.List;
/**
* 表单项转换的操作流程,即如下的 convert 方法(使用 final 修饰,确保子类不可修改操作流程)
*
* @author F嘉阳
* @date 2022/1/26 09:50
*/
public abstract class AbstractFormItemConverter {
/**
* 子类可处理的表单项类型
*/
public abstract ComponentTypeEnum getType();
/**
* 将输入的配置转变为表单项的操作流程
*
* @param config 前端输入的配置
* @return 表单项
*/
public final FormItem convert(FormItemConfig config) {
FormItem item = createItem(config);
// 表单项创建完成之后,子类如果需要特殊处理,可覆写该方法
afterItemCreate(item, config);
FormComponentProps props = createComponentProps(config);
item.setComponentProps(props);
// 组件属性创建完成之后,子类如果需要特殊处理,可覆写该方法
afterPropsCreate(props, config);
List<FormItemRule> rules = createRules(config);
item.setRules(rules);
// 约束规则创建完成之后,子类如果需要特殊处理,可覆写该方法
afterRulesCreate(rules, config);
return item;
}
/**
* 共用逻辑:创建表单项、设置通用的表单项属性
*/
private FormItem createItem(FormItemConfig config) {
FormItem formItem = new FormItem();
formItem.setCode(config.getCode());
formItem.setTitle(config.getTitle());
formItem.setComponent(config.getComponent());
return formItem;
}
/**
* 表单项创建完成之后,子类如果需要特殊处理,可覆写该方法
*/
protected void afterItemCreate(FormItem item, FormItemConfig config) {
}
/**
* 共用逻辑:创建组件属性、设置通用的组件属性
*/
private FormComponentProps createComponentProps(FormItemConfig config) {
FormComponentProps props = new FormComponentProps();
if (config.isReadOnly()) {
props.setReadOnly(true);
}
if (StringUtils.isNotBlank(config.getPlaceholder())) {
props.setPlaceholder(config.getPlaceholder());
}
return props;
}
/**
* 组件属性创建完成之后,子类如果需要特殊处理,可覆写该方法
*/
protected void afterPropsCreate(FormComponentProps props, FormItemConfig config) {
}
/**
* 共用逻辑:创建约束规则、设置通用的约束规则
*/
private List<FormItemRule> createRules(FormItemConfig config) {
List<FormItemRule> rules = new ArrayList<>(4);
if (config.isRequired()) {
FormItemRule requiredRule = new FormItemRule();
requiredRule.setRequired(true);
requiredRule.setMessage("请输入" + config.getTitle());
rules.add(requiredRule);
}
return rules;
}
/**
* 约束规则创建完成之后,子类如果需要特殊处理,可覆写该方法
*/
protected void afterRulesCreate(List<FormItemRule> rules, FormItemConfig config) {
}
}

View File

@@ -0,0 +1,46 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItemConfig;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItemRule;
import java.util.List;
/**
* 通用文本类转换器
*
* @author F嘉阳
* @date 2022/1/26 09:54
*/
@Component
public abstract class AbstractTextConverter extends AbstractFormItemConverter {
/**
* 约束规则创建完成之后,子类如果需要特殊处理,可覆写该方法
*
* @param rules
* @param config
*/
@Override
protected void afterRulesCreate(List<FormItemRule> rules, FormItemConfig config) {
Integer minLength = config.getMinLength();
if (minLength != null && minLength > 0) {
FormItemRule minRule = new FormItemRule();
minRule.setMin(minLength);
minRule.setMessage("请至少输入 " + minLength + " 个字");
rules.add(minRule);
}
Integer maxLength = config.getMaxLength();
if (maxLength != null && maxLength > 0) {
FormItemRule maxRule = new FormItemRule();
maxRule.setMax(maxLength);
maxRule.setMessage("请最多输入 " + maxLength + " 个字");
rules.add(maxRule);
}
}
}

View File

@@ -0,0 +1,38 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.ComponentTypeEnum;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormComponentProps;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItemConfig;
/**
* 下拉选择框的转换器
*
* @author F嘉阳
* @date 2022/1/26 09:51
*/
@Component
public class DropdownSelectConverter extends AbstractFormItemConverter {
/**
* 子类可处理的表单项类型
*/
@Override
public ComponentTypeEnum getType() {
return ComponentTypeEnum.DROPDOWN_SELECT;
}
/**
* 组件属性创建完成之后,子类如果需要特殊处理,可覆写该方法
*
* @param props
* @param config
*/
@Override
protected void afterPropsCreate(FormComponentProps props, FormItemConfig config) {
props.setAutoWidth(false);
if (config.isMultiple()) {
props.setMode("multiple");
}
}
}

View File

@@ -0,0 +1,37 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.ComponentTypeEnum;
import java.util.EnumMap;
import java.util.List;
/**
* 简单工厂
*
* @author F嘉阳
* @date 2022/1/26 09:56
*/
@Component
public class FormItemConverterFactory {
private static final EnumMap<ComponentTypeEnum, AbstractFormItemConverter> CONVERTER_MAP = new EnumMap<>(ComponentTypeEnum.class);
/**
* 根据表单项类型获得对应的转换器
*
* @param type 表单项类型
* @return 表单项转换器
*/
public AbstractFormItemConverter getConverter(ComponentTypeEnum type) {
return CONVERTER_MAP.get(type);
}
@Autowired
public void setConverters(List<AbstractFormItemConverter> converters) {
for (final AbstractFormItemConverter converter : converters) {
CONVERTER_MAP.put(converter.getType(), converter);
}
}
}

View File

@@ -0,0 +1,46 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.ComponentTypeEnum;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormComponentProps;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItem;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItemConfig;
/**
* 模糊搜索框的转换器
*
* @author F嘉阳
* @date 2022/1/26 09:53
*/
@Component
public class FuzzySearchConverter extends AbstractFormItemConverter {
/**
* 子类可处理的表单项类型
*/
@Override
public ComponentTypeEnum getType() {
return ComponentTypeEnum.FUZZY_SEARCH;
}
/**
* 表单项创建完成之后,子类如果需要特殊处理,可覆写该方法
*
* @param item
* @param config
*/
@Override
protected void afterItemCreate(FormItem item, FormItemConfig config) {
item.setFuzzySearch(true);
}
/**
* 组件属性创建完成之后,子类如果需要特殊处理,可覆写该方法
*
* @param props
* @param config
*/
@Override
protected void afterPropsCreate(FormComponentProps props, FormItemConfig config) {
props.setAutoWidth(false);
}
}

View File

@@ -0,0 +1,22 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.ComponentTypeEnum;
/**
* 多行文本框的转换器
*
* @author F嘉阳
* @date 2022/1/26 09:56
*/
@Component
public class TextAreaConvertor extends AbstractTextConverter {
/**
* 子类可处理的表单项类型
*/
@Override
public ComponentTypeEnum getType() {
return ComponentTypeEnum.TEXT_AREA;
}
}

View File

@@ -0,0 +1,22 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.ComponentTypeEnum;
/**
* 单行文本框的转换器
*
* @author F嘉阳
* @date 2022/1/26 09:55
*/
@Component
public class TextInputConverter extends AbstractTextConverter {
/**
* 子类可处理的表单项类型
*/
@Override
public ComponentTypeEnum getType() {
return ComponentTypeEnum.TEXT_INPUT;
}
}

View File

@@ -16,4 +16,6 @@ public class FormComponentProps {
private boolean autoWidth;
private String mode;
private String placeholder;
}

View File

@@ -28,4 +28,6 @@ public class FormItemConfig {
private Integer minLength;
private Integer maxLength;
private String placeholder;
}

View File

@@ -1,17 +0,0 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* TODO:
*
* @author F嘉阳
* @date 2022/1/26 09:41
*/
@Getter
@AllArgsConstructor
public enum FormItemTypeEnum {
;
}

View File

@@ -1,4 +1,4 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring;
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.before;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.*;
@@ -7,6 +7,13 @@ import java.util.List;
/**
* 原始逻辑
* <p>
* 代码违反了 开闭原则对扩展开放对修改关闭如果此时需要添加一种新的表单项包含特殊的组件属性那么不可避免的要修改 convert 方法来进行新表单项的特殊处理
* <p>
* 观察上面的代码将配置转变为表单项 这个操作满足以下流程
* 创建表单项并设置通用的表单项属性然后再对不同表单项的特殊属性进行处理
* 创建组件属性处理通用的组件属性然后再对不同组件的特殊属性进行处理
* 创建约束规则处理通用的约束规则然后再对不同表单项的特性约束规则进行处理
*
* @author F嘉阳
* @date 2022/1/26 09:38

View File

@@ -0,0 +1,38 @@
package top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.after;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItem;
import top.fjy8018.designpattern.pattern.behavior.templatemethod.spring.bean.FormItemConfig;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Component
class FormItemConverterFactoryTest {
@Autowired
private FormItemConverterFactory factory;
public List<FormItem> convertFormItems(JSONArray inputConfigs) {
return IntStream.range(0, inputConfigs.size())
.mapToObj(inputConfigs::getJSONObject)
.map(this::convertFormItem)
.collect(Collectors.toList());
}
private FormItem convertFormItem(JSONObject inputConfig) {
FormItemConfig itemConfig = inputConfig.toJavaObject(FormItemConfig.class);
AbstractFormItemConverter converter = factory.getConverter(itemConfig.getType());
if (converter == null) {
throw new IllegalArgumentException("不存在转换器:" + itemConfig.getType());
}
return converter.convert(itemConfig);
}
}