Home >Java >javaTutorial >Introduction to Combination Pattern and Filter Pattern in Java Design Patterns (Code Example)

Introduction to Combination Pattern and Filter Pattern in Java Design Patterns (Code Example)

不言
不言Original
2018-09-12 16:10:171684browse

This article brings you an introduction to the combination mode and filter mode in Java design patterns (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. help.

Preface

In Previous article we learned about the appearance mode and decorator mode of structural mode. In this article, we will learn about combination mode and filter mode.

Composition mode

Introduction

The combination mode is used to treat a group of similar objects as a single object. The composition mode combines objects according to a tree structure, which is used to represent part and whole levels. This type of design pattern is a structural pattern, which creates a tree structure of groups of objects.

To put it simply, it is to combine similar objects according to the tree structure, and then indicate what the part is used for. There is a very vivid example in , which is the file system in the computer.

The file system consists of directories and files. Each directory can contain content. The contents of a directory can be files or directories. In this way, the computer's file system is organized in a recursive structure.

Of course, we can also use a simple example to explain the combination mode here.

In the school, there are many students, but these students have different identities. Some students are student union presidents, some are student union members, some are monitors, some are sports committee members, etc. Of course, most of them are ordinary students do not hold other positions. At this time we can use the combination mode to combine.

According to the management, the largest student position is the student union president. Under the student union president are the student union members, and then the student union members manage ordinary students. They are independent of each other and can become a part. can finally become a whole. It can be said that it is very consistent with the tree structure in the combination pattern to represent the 'part-whole' hierarchical structure.

No more nonsense, let’s develop the code below.
First define a student class with student name and position attributes.
Then add add(), remove(), get() methods in the student class, and finally make hierarchical calls.

Code example:

class Student{
    private String name;
    
    private String position;
    
    private List<Student> students;

    public Student(String name, String position) {
        this.name = name;
        this.position = position;
        students=new ArrayList<Student>();
    }
    
    
    public void add(Student student){
        students.add(student);
    }
    
    public void remove(Student student){
        students.remove(student);
    }
    
    public List<Student> get(){
        return students;
    }
    
    @Override
    public String toString() {
        return "Student [name=" + name + ", position=" + position + "]";
    }   
}


public class CompositeTest {

    public static void main(String[] args) {

        Student studentLeader=new Student("小明","学生会主席");

        Student committeeMember=new Student("小刚","学生会委员");
        
        Student student=new Student("小红","学生");
        
        committeeMember.add(student);
        studentLeader.add(committeeMember);
        
        System.out.println("-"+studentLeader);
        studentLeader.get().forEach(sl->{
            System.out.println("--"+sl);
            sl.get().forEach(cm->{
                System.out.println("---"+cm);
            });
        });
    }
}

Output result:

    -Student [name=小明, position=学生会主席]
    --Student [name=小刚, position=学生会委员]
    ---Student [name=小红, position=学生]

In the above example, we added three students ( More are the same, mainly ideas), playing the roles of student council president, student council member and student in the school. Among them, the student union president manages the student union members, and the student union committee members manage the students. There is a hierarchical relationship between them, layer by layer. In this, we also discovered that the combination mode is actually to include an object into another object, and then perform some layout through combination.

Advantages of the combination mode:

High-level module calls are relatively simple, and it is convenient to add a node.

Disadvantages of the combination mode:

Because the declarations of its child nodes are all implementation classes, not interfaces, it violates the dependency inversion principle.

Usage scenarios:
can be expressed as a hierarchical structure of ‘part-whole’.

Filter Pattern

Introduction

The Filter pattern allows developers to filter a set of objects using different criteria, decoupled through logical operations way to connect them. This type of design pattern is a structural pattern that combines multiple criteria to achieve a single criterion.

Simply speaking, the function of this mode is, as its name suggests, to function as a filter. When we usually develop background interfaces, we will also filter out some requests. In fact, the filter mode mainly implements this function. Without further ado, let’s start with the corresponding explanation in code.

Here we still use students to explain. There are boys and girls among the students in the school, and the school has different grades. At this time, if we count the relevant information of the students, we can use the filter mode to group them. . For example, count how many boys there are in the school, how many girls are in the first grade, how many third grade students or girls are there, etc.

Code example:
Since there is a lot of code, I will explain it separately here.
First define an entity class with three attributes: name, gender, and grade.

class Student{
    private String name; 
    private String gender; 
    private Integer grade;
    public Student(String name, String gender, Integer grade) {
        super();
        this.name = name;
        this.gender = gender;
        this.grade = grade;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getGender() {
        return gender;
    }
    
    public void setGender(String gender) {
        this.gender = gender;
    }
    
    public Integer getGrade() {
        return grade;
    }
    
    public void setGrade(Integer grade) {
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", gender=" + gender + ", grade=" + grade + "]";
    }
}

Then define a public interface and specify the implementation method.

interface FilterinGrule {
    List<Student>  filter(List<Student> students);
}

Then implement the interface and formulate different filtering rules. There are mainly three rules here, ordinary filtering, and filtering, or filtering.
The specific implementation method is as follows:

class MaleStudents implements FilterinGrule{
    @Override
    public List<Student> filter(List<Student> students) {
        List<Student> maleStudents = new ArrayList<Student>(); 
        students.forEach(student->{
             if(student.getGender().equalsIgnoreCase("male")){
                 maleStudents.add(student);
             }
        });
        return maleStudents;
    }
}

class FemaleStudents implements FilterinGrule{
    @Override
    public List<Student> filter(List<Student> students) {
        List<Student> femaleStudents = new ArrayList<Student>(); 
        students.forEach(student->{
             if(student.getGender().equalsIgnoreCase("female")){
                 femaleStudents.add(student);
             }
        });
        return femaleStudents;
    }
}

class SecondGrade implements FilterinGrule{
    @Override
    public List<Student> filter(List<Student> students) {
        List<Student> secondGradeStudents = new ArrayList<Student>(); 
        students.forEach(student->{
             if(student.getGrade() == 2){
                 secondGradeStudents.add(student);
             }
        });
        
        return secondGradeStudents;
    }
}


class And implements FilterinGrule{
     private FilterinGrule filter;
     private FilterinGrule filter2;
    
     public And(FilterinGrule filter,FilterinGrule filter2) {
         this.filter=filter;
         this.filter2=filter2;
     }
    
    @Override
    public List<Student> filter(List<Student> students) {
        List<Student> students2=filter.filter(students);
        return filter2.filter(students2);
    }
}

class Or implements FilterinGrule{
     private FilterinGrule filter;
     private FilterinGrule filter2;
    
     public Or(FilterinGrule filter,FilterinGrule filter2) {
         this.filter=filter;
         this.filter2=filter2;
     }
    
    @Override
    public List<Student> filter(List<Student> students) {
        List<Student> students1=filter.filter(students);
        List<Student> students2=filter2.filter(students);
        students2.forEach(student->{
             if(!students1.contains(student)){
                 students1.add(student);
             }
        });
        return students1;
    }
}

Finally, call the test, add some students, and specify the gender and class. Then filter based on different conditions.

public class FilterTest {

    public static void main(String[] args) {
        List<Student> list=new ArrayList<Student>();
        list.add(new Student("小明", "male", 1));
        list.add(new Student("小红", "female", 2));
        list.add(new Student("小刚", "male", 2));
        list.add(new Student("小霞", "female", 3));
        list.add(new Student("小智", "male", 3));
        list.add(new Student("虚无境", "male", 1));
        
        
        FilterinGrule male = new MaleStudents();
        FilterinGrule female = new FemaleStudents();
        FilterinGrule secondGrade = new SecondGrade();
        FilterinGrule secondGradeMale = new And(secondGrade, male);
        FilterinGrule secondGradeOrFemale = new Or(secondGrade, female);
        
        System.out.println("男生:"+male.filter(list));
        System.out.println("女生:"+female.filter(list));
        System.out.println("二年级学生:"+secondGrade.filter(list));
        System.out.println("二年级男生:"+secondGradeMale.filter(list));
        System.out.println("二年级的学生或女生:"+secondGradeOrFemale.filter(list));      
    }
}

Output result:

男生:[Student [name=小明, gender=male, grade=1], Student [name=小刚, gender=male, grade=2], Student [name=小智, gender=male, grade=3], Student [name=虚无境, gender=male, grade=1]]
女生:[Student [name=小红, gender=female, grade=2], Student [name=小霞, gender=female, grade=3]]
二年级学生:[Student [name=小红, gender=female, grade=2], Student [name=小刚, gender=male, grade=2]]
二年级男生:[Student [name=小刚, gender=male, grade=2]]
二年级的学生或女生:[Student [name=小红, gender=female, grade=2], Student [name=小刚, gender=male, grade=2], Student [name=小霞, gender=female, grade=3]]

通过上述示例,我们发现过滤器模式其实很简单,制定过滤规则,然后再根据制定的标准来进行过滤,得到符合条件的数据。过滤器模式虽然简单,但是在构建过滤规则的时候,有点繁琐,不过在jdk1.8之后,我们可以使用stream流更方便的进行规则的制定(这一点留在以后再讲)。

过滤器模式的优点:

简单,解耦,使用方便。

过滤器模式的缺点:

好像没有。。。

使用场景:

需要进行筛选的时候。

相关推荐:

Java设计模式中外观模式和装饰器模式的介绍(代码示例)

Java设计模式中适配器模式和桥接模式的介绍(代码示例)

The above is the detailed content of Introduction to Combination Pattern and Filter Pattern in Java Design Patterns (Code Example). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn