1.定义
过滤器模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。
2.好处
提高程序的可扩展性,假如新增过滤规则,只需要再编写一个实现过滤器接口的类即可。
3.案例
(1).需求描述
货源存在cargoId、cargoName和cargoCategory等字段,根据业务需求需要对货源字段进行过滤,如果有任意过滤规则不满足,则该货源不允许上架。
(2).Cargo
@Data
@AllArgsConstructor
public class Cargo {
private Long cargoId;
private String cargoName;
private String cargoCategory;
}
(3).Cargo
public interface ICargoFilter {
//过滤器执行顺序,值越小越先执行
int getOrder();
//过滤逻辑
boolean filter(Cargo cargo);
}
@Component
public class CargoIdCargoFilter implements ICargoFilter {
public int getOrder() {
return 30;
}
public boolean filter(Cargo cargo) {
if (cargo.getCargoId() < 0) {
System.out.println("cargoId不合法");
return false;
}
return true;
}
}
@Component
public class CargoNameCargoFilter implements ICargoFilter {
public int getOrder() {
return 20;
}
public boolean filter(Cargo cargo) {
if ("".equals(cargo.getCargoName())) {
System.out.println("货源名称为空");
return false;
}
return true;
}
}
@Component
public class CategoryCargoFilter implements ICargoFilter {
public int getOrder() {
return 10;
}
public boolean filter(Cargo cargo) {
if ("毒品".equals(cargo.getCargoCategory())) {
System.out.println("货源类别为禁运物品");
return false;
}
return true;
}
}
(4).CargoFilterServiceLocator
@Component
public class CargoFilterServiceLocator implements ApplicationContextAware {
/**
* 存储ICargoFilter接口的所有实现类
*/
private Map<String, ICargoFilter> cargoFilterMap;
private List<ICargoFilter> cargoFilterList;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
cargoFilterMap = applicationContext.getBeansOfType(ICargoFilter.class);
cargoFilterList = new ArrayList<>(cargoFilterMap.values());
}
/**
* 获取所有实现类
*
* @return
*/
public List<ICargoFilter> getAllList() {
Collections.sort(cargoFilterList, new Comparator<ICargoFilter>() {
@Override
public int compare(ICargoFilter o1, ICargoFilter o2) {
return o1.getOrder() - o2.getOrder();
}
});
return cargoFilterList;
}
}
(5).测试
@RunWith(SpringRunner.class)
@SpringBootTest
class SpringBootDemoApplicationTests {
@Autowired
private CargoFilterServiceLocator cargoFilterServiceLocator;
@Test
void contextLoads() {
}
@Test
void test() {
Cargo cargo = new Cargo(-10000l,"水果","毒品");
List<ICargoFilter> cargoFilters = cargoFilterServiceLocator.getAllList();
for(ICargoFilter cargoFilter:cargoFilters){
if(!cargoFilter.filter(cargo)){
break;
}
}
}
}
货源类别为禁运物品