前言在上一篇中我們學(xué)習(xí)了結(jié)構(gòu)型模式的外觀模式和裝飾器模式。本篇則來學(xué)習(xí)下組合模式和過濾器模式。 組合模式簡介
簡單來說的話,就是根據(jù)樹形結(jié)構(gòu)把相似的對象進行組合,然后表示該部分是用來做啥的。在<大話設(shè)計模式>中有個很形象的例子,就是電腦中的 文件系統(tǒng)。
當(dāng)然,這里我們也可以使用一個簡單的示例來對組合模式進行講解。 在學(xué)校中,有很多學(xué)生,但是這些學(xué)生中又有不同的身份,有的學(xué)生是學(xué)生會主席,有的是學(xué)生會委員,有的是班長,有的是體育委員等等, 當(dāng)然大部分都是普通的學(xué)生,并沒有擔(dān)當(dāng)其它的職位。這時我們就可以使用組合模式來進行組合。 按照管理層來看,學(xué)生職位中最大的是學(xué)生會主席,學(xué)生會主席下有學(xué)生會委員,然后學(xué)生會委員又管理著普通的學(xué)生,他們之間相互獨立,可以成為一個部分,也可以最終成為一個整體??梢哉f非常符合組合模式中的 廢話不在多說了,下面進行代碼的開發(fā)。 代碼示例: 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("小明","學(xué)生會主席"); Student committeeMember=new Student("小剛","學(xué)生會委員"); Student student=new Student("小紅","學(xué)生"); 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); }); }); } }
輸出結(jié)果: -Student [name=小明, position=學(xué)生會主席] --Student [name=小剛, position=學(xué)生會委員] ---Student [name=小紅, position=學(xué)生]
在上述示例中,我們添加了三個學(xué)生(更多也一樣,主要是思路),在學(xué)校中分別扮演 學(xué)生會主席、學(xué)生會委員以及學(xué)生。其中學(xué)生會主席管理著學(xué)生會委員,學(xué)生會委員管理著學(xué)生,他們之間屬于層級關(guān)系,一層層的包含。在這之中,我們也發(fā)現(xiàn)一點,其實組合模式就是把某個對象去包含另一個對象,然后通過組合的方式來進行一些布局。 組合模式的優(yōu)點:
組合模式的缺點:
使用場景: 過濾器模式簡介
簡單的來說該模式的功能就是如其名,做一個過濾的作用。我們在一般在進行后臺接口開發(fā)的時候,也會根據(jù)過濾掉一些請求。其實過濾器模式主要實現(xiàn)也是這種功能,廢話不多說,開始用代碼進行相應(yīng)的說明。 這里依舊用學(xué)生來進行講解,學(xué)校的學(xué)生中有男生和女生,學(xué)校又有不同的年級,這時我們相統(tǒng)計下學(xué)生的相關(guān)信息,就可以使用過濾器模式來進行分組了。比如,統(tǒng)計該學(xué)校有多少男生,一年級的女生有多少,三年級的學(xué)生或者女生有多少之類等等。 代碼示例: 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 + "]"; } }
然后再定義一個公用的接口,指定實現(xiàn)的方法。 interface FilterinGrule { List<Student> filter(List<Student> students); }
然后再實現(xiàn)該接口,制定不同的過濾規(guī)則。這里主要是三種規(guī)則,普通的過濾,且過濾,或過濾。 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; } }
最后再來進行調(diào)用測試,添加一些學(xué)生,并且指定性別以及班級。然后根據(jù)不同的條件來進行過濾。 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("二年級學(xué)生:"+secondGrade.filter(list)); System.out.println("二年級男生:"+secondGradeMale.filter(list)); System.out.println("二年級的學(xué)生或女生:"+secondGradeOrFemale.filter(list)); } }
輸出結(jié)果: 男生:[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]] 二年級學(xué)生:[Student [name=小紅, gender=female, grade=2], Student [name=小剛, gender=male, grade=2]] 二年級男生:[Student [name=小剛, gender=male, grade=2]] 二年級的學(xué)生或女生:[Student [name=小紅, gender=female, grade=2], Student [name=小剛, gender=male, grade=2], Student [name=小霞, gender=female, grade=3]]
通過上述示例,我們發(fā)現(xiàn)過濾器模式其實很簡單,制定過濾規(guī)則,然后再根據(jù)制定的標(biāo)準(zhǔn)來進行過濾,得到符合條件的數(shù)據(jù)。過濾器模式雖然簡單,但是在構(gòu)建過濾規(guī)則的時候,有點繁瑣,不過在jdk1.8之后,我們可以使用stream流更方便的進行規(guī)則的制定(這一點留在以后再講)。 過濾器模式的優(yōu)點:
過濾器模式的缺點:
使用場景:
|
|
來自: 新進小設(shè)計 > 《待分類》