过滤器模式属于设计模式里面的结构型模式。

这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。

常见的通用实现方法是通过ArrayLiat来作为容器存放对象并利用对象的多态对其进行操作。

设计思路:

  1. 创建一个要过滤的类,普通类即可,要有获得其私有属性的get方法
  2. 创建一个接口,规定过滤方法
  3. 实现接口,可以依需要来实现过滤的条件(通过重写过滤方法),参数传递的可以说List<过滤类>类的容器
  4. 复杂过滤类可以通过设置传递接口参数(复用其他基础过滤类)来实现多重过滤

设计一个小例子,水果的过滤,我们从一堆水果中取出自己想要的水果

代码如下:

import java.util.*;
class Fruit{
    private String name;
    private String taste;
    private String shape;
    Fruit(String name,String taste,String shape){
        this.name=name;
        this.taste=taste;
        this.shape=shape;
    }
    public String getName() {
        return name;
    }

    public String getTaste() {
        return taste;
    }

    public String getShape() {
        return shape;
    }


}

interface Criteria{
    public List<Fruit> meetCriteria(List<Fruit> allfruit);
}

class CriteriaName implements Criteria{

    @Override
    public List<Fruit> meetCriteria(List<Fruit> allfruit) {
        List<Fruit> oranges=new ArrayList<Fruit>();
        for(Fruit fruit:allfruit){
            if(fruit.getName()=="橘子"){
                oranges.add(fruit);
            }
        }
        return oranges;
    }

}

class CriteriaTaste implements Criteria{

    @Override
    public List<Fruit> meetCriteria(List<Fruit> allfruit) {
        List<Fruit> sweetfruit=new ArrayList<Fruit>();
        for(Fruit fruit:allfruit){
            if(fruit.getTaste()=="甜的"){
                sweetfruit.add(fruit);
            }
        }
        return sweetfruit;
    }

}

class CriteriaShape implements Criteria{

    @Override
    public List<Fruit> meetCriteria(List<Fruit> allfruit) {
        List<Fruit> circlefruit=new ArrayList<Fruit>();
        for(Fruit fruit:allfruit){
            if(fruit.getShape()=="圆形"){
                circlefruit.add(fruit);
            }
        }
        return circlefruit;
    }

}

class AndCriteria implements Criteria{      //多重过滤器类
    private Criteria criteria;
    private Criteria otherCriteria;

    public AndCriteria(Criteria criteria,Criteria otherCriteria){
        this.criteria=criteria;
        this.otherCriteria=otherCriteria;
    }


    @Override
    public List<Fruit> meetCriteria(List<Fruit> allfruit) {
        List<Fruit>  firstCriteriafruit=criteria.meetCriteria(allfruit);    //生成新的容器放置第一重过滤
        return otherCriteria.meetCriteria(firstCriteriafruit);              //第二重过滤
    }

}

class OrCriteria implements Criteria{
    private Criteria criteria;
    private Criteria otherCriteria;

    public OrCriteria(Criteria criteria,Criteria otherCriteria){
        this.criteria=criteria;
        this.otherCriteria=otherCriteria;
    }


    @Override
    public List<Fruit> meetCriteria(List<Fruit> allfruit) {
        List<Fruit>  firstCriteriaItems=criteria.meetCriteria(allfruit);        //第一重过滤放置一个新容器内
        List<Fruit>  otherCriteriaItems=otherCriteria.meetCriteria(allfruit);   //仍是第一重过滤放置一个新容器内
        for(Fruit fruit:otherCriteriaItems){                                    //对第二个新容器遍历
            if(!firstCriteriaItems.contains(fruit)){                            //对比第一个容器内的对象
                firstCriteriaItems.add(fruit);
            }
        }
        return firstCriteriaItems;
    }

}
public class FilterPatternDemo {

    public static void main(String[] args) {
        List<Fruit> allfruit=new ArrayList<Fruit>();

        allfruit.add(new Fruit("苹果","甜的 ","圆形"));
        allfruit.add(new Fruit("橘子","酸的", "圆形"));
        allfruit.add(new Fruit("菠萝","甜的", "椭圆"));
        allfruit.add(new Fruit("西瓜","甜的", "椭圆"));
        allfruit.add(new Fruit("枣子","酸的", "圆形"));

        Criteria circle = new CriteriaShape();
        Criteria sweet = new CriteriaTaste();
        Criteria orange = new CriteriaName();
        Criteria sweetorange = new AndCriteria(sweet, orange);      //构造器的作用,传参设置内部变量!!
        Criteria circleOrsweet = new OrCriteria(circle, sweet);

        System.out.println("橘子: ");
        printFruit((orange.meetCriteria(allfruit)));

        System.out.println("\n甜的: ");
          printFruit((sweet.meetCriteria(allfruit)));

          System.out.println("\n圆形: ");
          printFruit((circle.meetCriteria(allfruit)));

          System.out.println("\n甜的橘子: ");
          printFruit((sweetorange.meetCriteria(allfruit)));

          System.out.println("\n圆的或甜的:");
          printFruit(circleOrsweet.meetCriteria(allfruit));
    }
    public static void printFruit(List<Fruit> allfruit){
        for(Fruit fruit:allfruit){
            System.out.println("Fruit:[ Name :"+fruit.getName()+",Taste: "+fruit.getTaste()+",Shape:"+fruit.getShape()+"]");
        }
    }
}

输出:

橘子: 
Fruit:[ Name :橘子,Taste: 酸的,Shape:圆形]

甜的: 
Fruit:[ Name :菠萝,Taste: 甜的,Shape:椭圆]
Fruit:[ Name :西瓜,Taste: 甜的,Shape:椭圆]

圆形: 
Fruit:[ Name :苹果,Taste: 甜的 ,Shape:圆形]
Fruit:[ Name :橘子,Taste: 酸的,Shape:圆形]
Fruit:[ Name :枣子,Taste: 酸的,Shape:圆形]

甜的橘子: 

圆的或甜的:
Fruit:[ Name :苹果,Taste: 甜的 ,Shape:圆形]
Fruit:[ Name :橘子,Taste: 酸的,Shape:圆形]
Fruit:[ Name :枣子,Taste: 酸的,Shape:圆形]
Fruit:[ Name :菠萝,Taste: 甜的,Shape:椭圆]
Fruit:[ Name :西瓜,Taste: 甜的,Shape:椭圆]

总结:过滤器模式还是是非重要常用的一种设计模式,需要牢固记忆掌握,要区分好其他的结构型模式:比如加功能和减功能

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐