在上一篇中咱們學習告終構型模式的外觀模式和裝飾器模式。本篇則來學習下組合模式和過濾器模式。html
簡介設計模式
組合模式是用於把一組類似的對象看成一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及總體層次。這種類型的設計模式屬於結構型模式,它建立了對象組的樹形結構。ide
簡單來講的話,就是根據樹形結構把類似的對象進行組合,而後表示該部分是用來作啥的。在 <大話設計模式> 中有個很形象的例子,就是電腦中的 文件系統。 佈局
文件系統由目錄和文件組成。每一個目錄均可以裝內容。目錄的內容能夠是文件,也能夠是目錄。按照這種方式,計算機的文件系統就是以遞歸結構來組織的。學習
固然,這裏咱們也可使用一個簡單的示例來對組合模式進行講解。測試
在學校中,有不少學生,可是這些學生中又有不一樣的身份,有的學生是學生會主席,有的是學生會委員,有的是班長,有的是體育委員等等, 固然大部分都是普通的學生,並無擔當其它的職位。這時咱們就可使用組合模式來進行組合。this
按照管理層來看,學生職位中最大的是學生會主席,學生會主席下有學生會委員,而後學生會委員又管理着普通的學生,他們之間相互獨立,能夠成爲一個部分,也能夠最終成爲一個總體。能夠說很是符合組合模式中的樹形結構以表示‘部分-總體’的層次結構
。.net
廢話不在多說了,下面進行代碼的開發。
首先定義一個學生類,有學生姓名和職位屬性。
而後在學生類中在添加 add()、remove()、get()方法,最後進行層級調用。設計
代碼示例:code
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流更方便的進行規則的制定(這一點留在之後再講)。
過濾器模式的優勢:
簡單,解耦,使用方便。
過濾器模式的缺點:
好像沒有。。。
使用場景:
須要進行篩選的時候。
其實邊聽音樂便看博客很享受的~_~
原創不易,若是感受不錯,但願給個推薦!您的支持是我寫做的最大動力! 版權聲明: 做者:虛無境 博客園出處:http://www.cnblogs.com/xuwujing CSDN出處:http://blog.csdn.net/qazwsxpcm 我的博客出處:http://www.panchengming.com