设计模式之过滤器模式

来源:互联网 发布:淘宝快递模板 编辑:程序博客网 时间:2024/06/05 04:50

时候我们需要在一堆对象的集合里找到我们需要的对象,这种情况如果比较简单的过滤,我们可以简单的用if-else去判断,如果这种过滤是比较具有复用性质的过滤条件,例如在所有用户里筛选出成年人,还有就是在增加过滤条件的时候要去加if语句,不是特别的灵活,这个时候可以尝试用过滤器模式去解决问题。

值得一提的是与过滤器模式比较像的类似于责任链模式,它是解决了请求和处理请求的对象之间的解耦,侧重在于解耦,过滤器模式,侧重在于过滤条件的复用和组合。

过滤器模式的UML图如下:

这里写图片描述


我们来写个关于用户年龄和性别的过滤:

class User {    // Male or Female    protected String gender;    protected Integer age;    public User(String gender, Integer age) {        this.gender = gender;        this.age = age;    }    // Setter Getter    // toString}

然后是过滤器接口:

// 过滤器接口interface Filter {    Set<User> filter(Set<User> userSet);}

两种具体的过滤器:

// 筛选指定性别class GenderFilter implements Filter {    private String gender;    GenderFilter(String gender) {        this.gender = gender;    }    public Set<User> filter(Set<User> userSet) {        if (userSet == null) {            return null;        }        Set<User> filtUserSet = new HashSet<User>(userSet.size());        for (User user : userSet) {            if (this.gender.equals(user.getGender())) {                filtUserSet.add(user);            }        }        return filtUserSet;    }}// 年龄段过滤class AgeFilter implements Filter {    private Integer age;    public AgeFilter(Integer age) {        this.age = age;    }    public Set<User> filter(Set<User> userSet) {        if (userSet == null) {            return null;        }        Set<User> newUserSet = new HashSet<User>(userSet.size());        for (User user : userSet) {            // 获取成年人            if (user.getAge() > this.age) {                newUserSet.add(user);            }        }        return newUserSet;    }}

第一种方式是设置为抽象类,然后维护下一个过滤器的引用,组成一种类似于链表的结构,例如:

abstract class AbstractFilter {    protected AbstractFilter nextFitler;    AbstractFilter(AbstractFilter filter) {        this.nextFilter = filter;    }    public Set<User> filterChain(Set<User> userSet) {        Set<User> filtUserSet = filter(userSet);        if (nextFilter != null) {            return nextFilter.filter(userSet);        }    }    public abstract Set<User> filter(Set<User> userSet);}

然后具体的过滤器:

class AgeFilter extends AbstractFilter {    private Integer age;    public AgeFilter2(AbstractFilter filter, Integer age) {        super(filter);        this.age = age;    }    public Set<User> filter(Set<User> userSet) {        Set<User> filtUserSet = new HashSet<User>();        for (User user : userSet) {            if (user.getAge() > this.age) {                filtUserSet.add(user);            }        }        return filtUserSet;    }}class GenderFilter extends AbstractFilter {    private String gender;    public GenderFilter2(AbstractFilter filter, String gender) {        super(filter);        this.gender = gender;    }    public Set<User> filter(Set<User> userSet) {        Set<User> filtUserSet = new HashSet<User>();        for (User user : userSet) {            if (this.gender.equals(user.getGender())) {                filtUserSet.add(user);            }        }        return filtUserSet;    }}

然后测试代码:

// 随机生成100个人        Random r = new Random();        Set<User> userSet = new HashSet<User>(100);        for (int i = 0;i < 100;i ++) {            userSet.add(new User(r.nextInt(100) % 2 == 0 ? "Male" : "Female", r.nextInt(100)));        }AbstractFilter abstractFilter = new AgeFilter2(new GenderFilter2(null, "Male"), 60);        Set<User> filterUserSet = abstractFilter.filter(userSet);        System.out.println(filterUser);

这样需要去构造过滤链,如果我们要复用过滤器的组合,我们可以用个类把组合条件封装


第二种方式

class Filters {    private static List<Filter> filters = new ArrayList<Filter>();;    public static void addFilter(Filter filter) {        filters.add(filter);    }    /**     * 过滤     */    public static Set<User> filerChain(Set<User> userSet) {        Set<User> filterUserSet = null;        for (Filter filter : filters) {            if (filterUserSet != null) {                filterUserSet = filter.filter(filterUserSet);            } else {                filterUserSet = filter.filter(userSet);            }        }        return filterUserSet;    }}
// 过滤器接口interface Filter {    Set<User> filter(Set<User> userSet);}
// 筛选指定性别class GenderFilter implements Filter {    private String gender;    GenderFilter(String gender) {        this.gender = gender;    }    public Set<User> filter(Set<User> userSet) {        if (userSet == null) {            return null;        }        Set<User> filtUserSet = new HashSet<User>(userSet.size());        for (User user : userSet) {            if (this.gender.equals(user.getGender())) {                filtUserSet.add(user);            }        }        return filtUserSet;    }}// 年龄段过滤class AgeFilter implements Filter {    private Integer age;    public AgeFilter(Integer age) {        this.age = age;    }    public Set<User> filter(Set<User> userSet) {        if (userSet == null) {            return null;        }        Set<User> newUserSet = new HashSet<User>(userSet.size());        for (User user : userSet) {            // 获取成年人            if (user.getAge() > this.age) {                newUserSet.add(user);            }        }        return newUserSet;    }}

测试代码:

AbstractFilter abstractFilter = new AgeFilter2(new GenderFilter2(null, "Male"), 60);        Set<User> filterUserSet = abstractFilter.filter(userSet);        System.out.println(filterUser);

过滤器模式就是解决了大堆对象的筛选。

原创粉丝点击