首頁 >Java >java教程 >Java設計模式中組合模式和過濾器模式的介紹(程式碼範例)

Java設計模式中組合模式和過濾器模式的介紹(程式碼範例)

不言
不言原創
2018-09-12 16:10:171655瀏覽

這篇文章帶給大家的內容是關於Java設計模式中組合模式和過濾器模式的介紹(程式碼範例) ,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

前言

上一篇中我們學習了結構型模式的外觀模式和裝飾器模式。本篇則來學習下組合模式和濾鏡模式。

組合模式

簡介

組合模式是用來把一組相似的物件當作單一的物件。組合模式依據樹狀結構來組合對象,用來表示部分以及整體層次。這種類型的設計模式屬於結構型模式,它創建了物件群組的樹狀結構。

簡單來說的話,就是根據樹狀結構把相似的物件進行組合,然後表示該部分是用來做啥的。在中有個很形象的例子,就是電腦中的 檔案系統

檔案系統由目錄和檔案組成。每個目錄都可以裝內容。目錄的內容可以是文件,也可以是目錄。依照這種方式,電腦的檔案系統就是以遞歸結構來組織的。

當然,這裡我們也可以使用一個簡單的範例來對組合模式進行講解。

在學校中,有很多學生,但是這些學生中又有不同的身份,有的學生是學生會主席,有的是學生會委員,有的是班長,有的是體育委員等等, 當然大部分都是普通的學生,並沒有擔任其它的職位。這時我們就可以使用組合模式來進行組合。

按照管理階層來看,學生職位中最大的是學生會主席,學生會主席下有學生會委員,然後學生會委員又管理著普通的學生,他們之間相互獨立,可以成為一個部分,也可以最終成為一個整體。可以說非常符合組合模式中的樹狀結構以表示『部分-整體』的層次結構

廢話不在多說了,以下進行程式碼的開發。
先定義一個學生類,有學生姓名和職位屬性。
接著在學生類別中在新增 add()、remove()、get()方法,最後進行層級呼叫。

程式碼範例:

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);
            });
        });
    }
}

輸出結果:

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

在上述範例中,我們新增了三個學生(更多也一樣,主要是想法),在學校中分別扮演學生會主席、學生會委員以及學生。其中學生會主席管理學生會委員,學生會委員管理學生,他們之間屬於層級關係,一層層的包含。在這之中,我們也發現一點,其實組合模式就是把某個對象去包含另一個對象,然後透過組合的方式來進行一些佈局。

組合模式的優點:

高層模組呼叫較為簡單,增加某個節點方便。

組合模式的缺點:

因為其子節點的宣告都是實作類,而不是接口,違反了依賴倒置原則。

使用場景:
可以表示為 ‘部分-整體’的層級結構。

過濾器模式

簡介

過濾器模式允許開發人員使用不同的標準來過濾一組對象,透過邏輯運算以解耦的方式把它們連接起來。這種類型的設計模式屬於結構型模式,它結合多個標準來獲得單一標準。

簡單的來說該模式的功能就是如其名,做一個過濾的作用。我們在一般在進行後台介面開發的時候,也會根據過濾掉一些請求。其實濾鏡模式主要實作也是這種功能,廢話不多說,開始用程式碼做對應的說明。

這裡依舊用學生來進行講解,學校的學生中有男生和女生,學校又有不同的年級,這時我們相統計下學生的相關信息,就可以使用過濾器模式來進行分組了。例如,統計該學校有多少男生,一年級的女生有多少,三年級的學生或女生有多少等。

程式碼範例:
由於程式碼有點多,這裡就分開進行解說。
先定義一個實體類,有姓名、性別、年級這三個屬性。

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 + "]";
    }
}

然後再定義一個公用的接口,指定實現的方法。

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

然後再實作該接口,制定不同的過濾規則。這裡主要是三種規則,普通的過濾,且過濾,或過濾。
具體實現的方法如下:

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;
    }
}

最後再來進行呼叫測試,新增一些學生,並且指定性別以及班級。然後根據不同的條件來進行過濾。

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));      
    }
}

輸出結果:

男生:[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设计模式中适配器模式和桥接模式的介绍(代码示例)

以上是Java設計模式中組合模式和過濾器模式的介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn