2023-05-17 更新
工厂混责任链和模板模式实现,实现讲解
目的 :多场景处理器实现,处理器内部启用近链式结构来满足负责不同场景下的检验的拆分
实现的思路是 : 首先我们先实现多个过滤器(实现检验的拆分),通过list实现过滤器链,也可以通过node节点的形式。再创建FilterType(过滤类型)辨别选取那个过滤器链。
第一步: 创建一个简单工厂实现过滤器的存储
@Service
@Data
public class FilterFactory {
// 这里的初始化为8应该按具体情况调节,map的扩容是繁琐的复制,开始时的大小定好能减少扩容的次数
private ConcurrentMap<FilterType, List<Filter>> filterMap = new ConcurrentHashMap<>(8);
}
第二步: 实现过滤器的抽象,场景码的定义,场景信息固化的存储
依赖抽象不依赖具体,在外部使用一个interface过滤器做为主过滤接口
再创建枚举FilterType实现场景分类
最后创建FilterContext作为适应不同场景的抽象用于存储场景信息,这里可以随时扩展
/**
* @Author Jinx
*/
@Service
@Data
public class FilterFactory {
public interface Filter {
/**
* 抽象过滤器
* @param filterContext
* @return
*/
String filter(FilterFactory.FilterContext filterContext);
}
@Getter
@AllArgsConstructor
public enum FilterType {
/**
* 过滤器应用类型
*/
LOCAL("local"),
ALL("all"),
DEV("dev");
private String type;
}
@Data
public static class FilterContext {
private String length;
private String name;
}
private ConcurrentMap<FilterType, List<Filter>> filterMap = new ConcurrentHashMap<>(8);
}
第三步: 再在工厂中实现注册方法和处理方法
public void register(FilterType type, Filter filter) {
List<Filter> filters = filterMap.get(type);
if (null==filters) {
List<Filter> filters1 = new ArrayList<>();
filters1.add(filter);
// 这里是一个系统错误,list.of()和Arrays.asList()会导致 Failed to load ,ApplicationContext,因为这个是个视图类,没有新增操作,新增add方法在父类会抛出Failed to load
// List<Filter> filters1 = Arrays.asList(filter);
filterMap.put(type,filters1);
} else {
filters.add(filter);
filterMap.put(type,filters);
}
System.out.println("1");
}
public String filter(FilterType type, FilterContext filterContext) {
List<Filter> filters = filterMap.getOrDefault(type, null);
if (null == filters) {
return "";
}
StringBuilder builder = new StringBuilder();
for (Filter filter : filters) {
String filterMessage = filter.filter(filterContext);
if (StringUtils.hasText(filterMessage)) {
builder.append(filterMessage);
}
}
return builder.toString();
}
第四步: 再次优化,如果共同方法再抽象一层,这里抽象一个注册方法,用于处理链的注册
/**
* 抽象过滤器
*
* @author Jinx
*/
@RequiredArgsConstructor
@Component
public abstract class AbsFilter implements FilterFactory.Filter {
private final FilterFactory filterFactory;
/**
* 抽象注册器入口
*/
public abstract void register();
/**
* 实际注册器
*
* @param type
*/
protected void doRegister(FilterFactory.FilterType type, FilterFactory.Filter filter) {
this.filterFactory.register(type, filter);
}
}
第五步: 实现注册长度和名称过滤器并注册到各个场景
/**
* @author Jinx
*/
@Component
public class LengthFilter extends AbsFilter {
public LengthFilter(FilterFactory filterFactory) {
super(filterFactory);
}
@Override
public String filter(FilterFactory.FilterContext filterContext) {
if (filterContext.getLength().length()>10){
return " str length beyond max ";
}
return "";
}
@PostConstruct
@Override
public void register() {
super.doRegister(FilterFactory.FilterType.LOCAL,this);
super.doRegister(FilterFactory.FilterType.ALL,this);
}
}
2
/**
* @author Jinx
*/
@Component
public class NameFilter extends AbsFilter{
public NameFilter(FilterFactory filterFactory) {
super(filterFactory);
}
@Override
public String filter(FilterFactory.FilterContext filterContext) {
String name = filterContext.getName();
if (name.equals("baga")){
return "八嘎";
}
return filterContext.getName();
}
@PostConstruct
@Override
public void register() {
super.doRegister(FilterFactory.FilterType.ALL,this);
super.doRegister(FilterFactory.FilterType.DEV,this);
}
}
第六步: 启动测试类,测试过滤器
@SpringBootTest
class ShdlfghkApplicationTests {
@Resource
FilterFactory filterFactory;
@Test
void mai22n() {
FilterFactory.FilterContext filterContext = new FilterFactory.FilterContext();
filterContext.setName("baga");
String msg = filterFactory.filter(FilterFactory.FilterType.DEV, filterContext);
System.out.println(msg);
filterContext.setLength("12345678910");
String msg1 = filterFactory.filter(FilterFactory.FilterType.LOCAL, filterContext);
System.out.println(msg1);
String msg2 = filterFactory.filter(FilterFactory.FilterType.ALL, filterContext);
System.out.println(msg2);
}
}
输出
nameless
str length beyond max
str length beyond max nameless