设计模式 - 过滤器模式

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快!

引言

过滤器模式(Filter Pattern),也称为标准模式(Criteria Pattern)或链式模式(Chain of Filters Pattern),是一种设计模式,用于从一组对象中筛选出满足特定条件的对象。这种模式通常用于数据库查询或者用户界面中的搜索功能。本文将详细介绍过滤器模式的概念,并通过具体的Java代码示例来说明如何实现这一模式。

一、过滤器模式的基本概念

过滤器模式的主要参与者包括:

  1. Criteria:定义了过滤接口。
  2. Concrete Criteria:实现了 Criteria 接口,提供了具体的过滤逻辑。
  3. And Criteria:组合多个 Criteria 来创建更复杂的过滤条件。
  4. Or Criteria:同样用于组合 Criteria,但是用于满足任意一个条件的场景。
  5. Client:使用 Criteria 来过滤数据。

二、过滤器模式的实现

接下来,我们将通过一个示例来详细了解过滤器模式的实现步骤。假设我们有一个人员管理系统,需要根据不同的条件来筛选员工列表。

1. 定义过滤接口

首先,定义过滤接口:

public interface Criteria {
    List<Person> meetCriteria(List<Person> persons);
}
2. 定义具体过滤条件

接下来,定义具体过滤条件的实现类:

public class Person {
    private String name;
    private String gender;
    private String maritalStatus;

    public Person(String name, String gender, String maritalStatus) {
        this.name = name;
        this.gender = gender;
        this.maritalStatus = maritalStatus;
    }

    public String getName() {
        return name;
    }

    public String getGender() {
        return gender;
    }

    public String getMaritalStatus() {
        return maritalStatus;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", maritalStatus='" + maritalStatus + '\'' +
                '}';
    }
}

public class MaleCriteria implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> malePersons = new ArrayList<>();
        for (Person person : persons) {
            if ("MALE".equalsIgnoreCase(person.getGender())) {
                malePersons.add(person);
            }
        }
        return malePersons;
    }
}

public class FemaleCriteria implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> femalePersons = new ArrayList<>();
        for (Person person : persons) {
            if ("FEMALE".equalsIgnoreCase(person.getGender())) {
                femalePersons.add(person);
            }
        }
        return femalePersons;
    }
}

public class SingleCriteria implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> singlePersons = new ArrayList<>();
        for (Person person : persons) {
            if ("SINGLE".equalsIgnoreCase(person.getMaritalStatus())) {
                singlePersons.add(person);
            }
        }
        return singlePersons;
    }
}
3. 定义组合过滤条件

接下来,定义组合过滤条件的实现类:

public class AndCriteria implements Criteria {
    private Criteria criteria;
    private Criteria otherCriteria;

    public AndCriteria(Criteria criteria, Criteria otherCriteria) {
        this.criteria = criteria;
        this.otherCriteria = otherCriteria;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
        return otherCriteria.meetCriteria(firstCriteriaPersons);
    }
}

public class OrCriteria implements Criteria {
    private Criteria criteria;
    private Criteria otherCriteria;

    public OrCriteria(Criteria criteria, Criteria otherCriteria) {
        this.criteria = criteria;
        this.otherCriteria = otherCriteria;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
        List<Person> secondCriteriaPersons = otherCriteria.meetCriteria(persons);

        for (Person person : secondCriteriaPersons) {
            if (!firstCriteriaPersons.contains(person)) {
                firstCriteriaPersons.add(person);
            }
        }

        return firstCriteriaPersons;
    }
}
4. 客户端代码

客户端代码使用 Criteria 来创建具体过滤条件对象,并调用其方法:

public class CriteriaPatternDemo {
    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();

        // 初始化人员列表
        persons.add(new Person("Robert", "MALE", "MARRIED"));
        persons.add(new Person("John", "MALE", "SINGLE"));
        persons.add(new Person("Laura", "FEMALE", "MARRIED"));
        persons.add(new Person("Diana", "FEMALE", "SINGLE"));
        persons.add(new Person("Mike", "MALE", "SINGLE"));
        persons.add(new Person("Bobby", "MALE", "SINGLE"));

        Criteria male = new MaleCriteria();
        Criteria female = new FemaleCriteria();
        Criteria single = new SingleCriteria();
        Criteria singleMale = new AndCriteria(single, male);
        Criteria singleOrFemale = new OrCriteria(single, female);

        System.out.println("Males: ");
        printPersons(male.meetCriteria(persons));

        System.out.println("\nFemales: ");
        printPersons(female.meetCriteria(persons));

        System.out.println("\nSingle Males: ");
        printPersons(singleMale.meetCriteria(persons));

        System.out.println("\nSingle Or Females: ");
        printPersons(singleOrFemale.meetCriteria(persons));
    }

    private static void printPersons(List<Person> persons) {
        for (Person person : persons) {
            System.out.println("Person : [Name : " + person.getName()
                    + ", Gender : " + person.getGender()
                    + ", Marital Status : " + person.getMaritalStatus() + "]");
        }
    }
}

三、过滤器模式的优点

  1. 扩展性:可以轻松地添加新的 Criteria 类来满足新的过滤要求。
  2. 复用性:不同的 Criteria 可以被组合起来形成更复杂的过滤条件。
  3. 清晰性:每个 Criteria 类只关注单一的过滤逻辑,这使得代码更加清晰易懂。

四、过滤器模式的缺点

  1. 性能问题:如果 Criteria 需要在大量数据上进行操作,则可能会导致性能问题。
  2. 代码膨胀:随着 Criteria 的增多,代码量可能会变得庞大。

五、过滤器模式的应用场景

过滤器模式适用于以下情况:

  1. 查询操作:当需要在数据库查询中使用复杂的过滤条件时。
  2. 用户界面:当需要在用户界面上提供高级搜索功能时。
  3. 多条件组合:当需要组合多个过滤条件来实现更复杂的逻辑时。

六、过滤器模式的扩展

在实际应用中,可以通过以下方式扩展过滤器模式:

  1. 动态组合:允许在运行时动态地组合 Criteria 对象。
  2. 参数化 Criteria:允许通过参数来指定具体的过滤条件,从而在运行时动态选择过滤条件。
1. 动态组合 Criteria
public class CriteriaPatternDemo {
    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        // 初始化人员列表

        Criteria male = new MaleCriteria();
        Criteria female = new FemaleCriteria();
        Criteria single = new SingleCriteria();

        Criteria criteria = new OrCriteria(new AndCriteria(male, single), female);

        System.out.println("Criteria: Single Male or Female");
        printPersons(criteria.meetCriteria(persons));
    }
}
2. 参数化 Criteria
public class CriteriaPatternDemo {
    public static void main(String[] args) {
        List<Person> persons = new ArrayList<>();
        // 初始化人员列表

        Criteria criteria = createCriteria("male", "single");

        System.out.println("Criteria: Male and Single");
        printPersons(criteria.meetCriteria(persons));
    }

    private static Criteria createCriteria(String gender, String maritalStatus) {
        Criteria genderCriteria = null;
        Criteria maritalStatusCriteria = null;

        if ("male".equalsIgnoreCase(gender)) {
            genderCriteria = new MaleCriteria();
        } else if ("female".equalsIgnoreCase(gender)) {
            genderCriteria = new FemaleCriteria();
        }

        if ("single".equalsIgnoreCase(maritalStatus)) {
            maritalStatusCriteria = new SingleCriteria();
        } else if ("married".equalsIgnoreCase(maritalStatus)) {
            maritalStatusCriteria = new MarriedCriteria(); // 假设这里有一个 MarriedCriteria 类
        }

        if (genderCriteria != null && maritalStatusCriteria != null) {
            return new AndCriteria(genderCriteria, maritalStatusCriteria);
        }

        return null;
    }
}

七、过滤器模式与其他设计模式的关系

过滤器模式经常与工厂模式、策略模式等结合使用。例如,可以使用工厂模式来创建 Criteria 对象,使用策略模式来动态改变过滤策略。

八、总结

过滤器模式是面向对象设计中一种非常有用的模式,特别是在需要处理复杂查询和过滤条件时。在实际编程中,过滤器模式可以用于构建高度可配置和可扩展的系统,尤其是在需要支持多种不同类型的过滤条件时。通过上述实现,你可以根据自己的需求进一步扩展和优化过滤器模式的应用。

过滤器模式虽然简单,但在设计系统时需要考虑到其潜在的问题,比如性能问题和代码膨胀等。正确地使用过滤器模式可以使你的代码更加健壮和易于维护。


💝💝💝如有需要请大家订阅我的专栏【设计模式】哟!我会定期更新相关系列的文章
💝💝💝关注!关注!!请关注!!!请大家关注下博主,您的支持是我不断创作的最大动力!!!

设计模式相关文章索引文章链接
设计模式 - 抽象工厂模式 设计模式 - 抽象工厂模式
设计模式 - 单例模式 设计模式 - 单例模式
设计模式 - 建造者模式 设计模式 - 建造者模式
设计模式 - 原型模式 设计模式 - 原型模式
设计模式 - 适配器模式 设计模式 - 适配器模式
设计模式 - 桥接模式 设计模式 - 桥接模式

❤️❤️❤️觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟小码

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值