设计模式-过滤器模式

特点

过滤器模式也叫标准模式,允许开发人员根据标准过滤一组对象,通过逻辑运算解耦应用程序。

程序代码

pojo 对象Person类

@Slf4j
@Data
@Accessors(chain = true)
public class Person {
    private int age;

    private boolean married;

    private int sex;
}

标准接口类

public interface Criterion {
    List<Person> filter(List<Person> persons);
}

按照年龄查询

public class AgeCriterion implements Criterion{
    private int[] age;

    public AgeCriterion(int[] age) {
        this.age = age;
    }

    @Override
    public List<Person> filter(List<Person> persons) {
        return persons.stream().filter(person -> person.getAge() >= age[0])
                .filter(person -> person.getAge() <= age[1])
                .collect(Collectors.toList());
    }
}

按照婚姻状况查询

@Slf4j
public class MarriedCriterion implements Criterion{
    private boolean married;

    public MarriedCriterion(boolean married) {
        this.married = married;
    }

    @Override
    public List<Person> filter(List<Person> persons) {
        return persons.stream().filter(person -> person.isMarried() == married)
                .collect(Collectors.toList());
    }
}

按照性别查询

public class SexCriterion implements Criterion{

    private int sex;
    public SexCriterion(int sex){
        this.sex = sex;
    }
    @Override
    public List<Person> filter(List<Person> persons) {
        return persons.stream()
                .filter(person -> person.getSex() == sex)
                .collect(Collectors.toList());
    }
}

组合查询

public class AndCriterion implements Criterion{
    private List<Criterion> criterions = new ArrayList<>();

    public AndCriterion(Criterion criterion) {
        this.criterions.add(criterion);
    }

    @Override
    public List<Person> filter(List<Person> persons) {
        List<Person> resList = persons;
        for (int i = 0; i < criterions.size(); i++) {
            Criterion criterion = criterions.get(i);
            resList = criterion.filter(resList);
        }
        return resList;
    }

    public AndCriterion add(Criterion criterion){
        this.criterions.add(criterion);
        return this;
    }

}

测试代码

组装数据

private List<Person> list (){
    return Arrays.asList(
            new Person().setAge(18).setMarried(false).setSex(0),
            new Person().setAge(19).setMarried(false).setSex(0),
            new Person().setAge(20).setMarried(true).setSex(0),
            new Person().setAge(21).setMarried(true).setSex(1),
            new Person().setAge(25).setMarried(true).setSex(1)
    );
}

测试

@Test
public void testCriterion(){
    List<Person> list = list();

    // 获取18-20的人
    Criterion ageCriterion = new AgeCriterion(new int[]{18, 20});
    List<Person> list1 = ageCriterion.filter(list);
    log.info("18-20过滤结果: {}",list1);

    // 获取已结婚的
    Criterion marriedCriterion = new MarriedCriterion(true);
    List<Person> list2 = marriedCriterion.filter(list);
    log.info("已结婚过滤结果: {}",list2);

    // 获取性别为男
    Criterion sexCriterion = new SexCriterion(0);
    List<Person> list3 = sexCriterion.filter(list);
    log.info("性别为男过滤结果: {}",list3);

    // 获取年龄 18-20 并且已婚 并且性别为男
    AndCriterion andCriterion = new AndCriterion(ageCriterion)
            .add(marriedCriterion)
            .add(sexCriterion);
    List<Person> list4 = andCriterion.filter(list);
    log.info("年龄 18-20 并且已婚 并且性别为男过滤结果: {}",list4);

}

日志信息

17:16:42.756 [main] INFO org.example.singleton.CriterionTest - 18-20过滤结果: [Person(age=18, married=false, sex=0), Person(age=19, married=false, sex=0), Person(age=20, married=true, sex=0)]
17:16:42.765 [main] INFO org.example.singleton.CriterionTest - 已结婚过滤结果: [Person(age=20, married=true, sex=0), Person(age=21, married=true, sex=1), Person(age=25, married=true, sex=1)]
17:16:42.766 [main] INFO org.example.singleton.CriterionTest - 性别为男过滤结果: [Person(age=18, married=false, sex=0), Person(age=19, married=false, sex=0), Person(age=20, married=true, sex=0)]
17:16:42.767 [main] INFO org.example.singleton.CriterionTest - 年龄 18-20 并且已婚 并且性别为男过滤结果: [Person(age=20, married=true, sex=0)]

从代码来看,实现了代码解耦,当需要添加条件时,无需更改比较代码逻辑。满足开闭原则。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值