Java进阶篇设计模式之六 ----- 组合模式和过滤器模式

前言

上一篇中咱们学习告终构型模式的外观模式和装饰器模式。本篇则来学习下组合模式和过滤器模式。html

组合模式

简介设计模式

组合模式是用于把一组类似的对象看成一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及总体层次。这种类型的设计模式属于结构型模式,它建立了对象组的树形结构。bash

简单来讲的话,就是根据树形结构把类似的对象进行组合,而后表示该部分是用来作啥的。在<大话设计模式>中有个很形象的例子,就是电脑中的 文件系统ide

文件系统由目录和文件组成。每一个目录均可以装内容。目录的内容能够是文件,也能够是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。布局

固然,这里咱们也可使用一个简单的示例来对组合模式进行讲解。学习

在学校中,有不少学生,可是这些学生中又有不一样的身份,有的学生是学生会主席,有的是学生会委员,有的是班长,有的是体育委员等等, 固然大部分都是普通的学生,并无担当其它的职位。这时咱们就可使用组合模式来进行组合。测试

按照管理层来看,学生职位中最大的是学生会主席,学生会主席下有学生会委员,而后学生会委员又管理着普通的学生,他们之间相互独立,能够成为一个部分,也能够最终成为一个总体。能够说很是符合组合模式中的树形结构以表示‘部分-总体’的层次结构ui

废话不在多说了,下面进行代码的开发。 首先定义一个学生类,有学生姓名和职位属性。 而后在学生类中在添加 add()、remove()、get()方法,最后进行层级调用。this

代码示例:spa

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流更方便的进行规则的制定(这一点留在之后再讲)。

过滤器模式的优势:

简单,解耦,使用方便。

过滤器模式的缺点:

好像没有。。。

使用场景:

须要进行筛选的时候。

其它

音乐推荐

其实边听音乐便看博客很享受的~_~

原创不易,若是感受不错,但愿给个推荐!您的支持是我写做的最大动力! 版权声明: 做者:虚无境
博客园出处:www.cnblogs.com/xuwujing CSDN出处:blog.csdn.net/qazwsxpcm  我的博客出处:www.panchengming.com