【问题标题】:Good design pattern for running a process on a collection of data?在数据集合上运行进程的良好设计模式?
【发布时间】:2011-01-26 11:45:53
【问题描述】:

我认为最好用代码来解释,这只是一个简单的例子:

public class MyPOJO {

    public String name;
    public int age;

    public MyPOJO(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class MyProcessor {

    public List<MyPOJO> process(List<MyPOJO> mypojos) {
        List<MyPOJO> temp = new ArrayList<MyPOJO>; 
        for (int i=0; i <moypojos.size(); i++) {
            if (filterOne(mypojos[i])) continue;
            if (filterTwo(mypojos[i])) continue;
            if (filterThree(mypojos[i])) continue;
            temp.add(mypojos[i];
        }
    }

    public boolean filterOne(MyPOJO mypojo) {
        // in practice filters aren't so basic
        return (mypojo.age < 21);
    }
    // assume implementations for the other filter methods
}

哎呀,太丑了。基本上我有一个集合,我想通过某种筛子将它传递给仅继续处理满足特定条件的对象。我的猜测是有一个比一堆返回布尔值的方法更好的模式。

【问题讨论】:

    标签: java design-patterns collections filter sieve


    【解决方案1】:

    你可以有IFilters的列表。

    像这样

    boolean filtersResult = false;
    for (IFilter filter : filters) {
        filterResult = filter.process(mypojos[i])
    
        if (filterResult)
            break;
    }
    

    【讨论】:

    • 将过滤器变成对象可以让您轻松地传递它们。因此,您可以将列表连同您要应用的每个过滤器的实例一起传递给处理器。这可能是处理这个问题的最好方法。
    • 好的,我知道我正在稍微改变问题,但是假设其中一个过滤器需要过滤掉 mypojo,如果它的年龄在一组糟糕的年龄中?所以我们有一个需要与之比较的 Set。我是否将接口方法修改为也采用 Set 参数而不将其用于其他过滤器?
    • 它将是一个过滤器,它在构造函数中接收一组年龄,并使用传递的集合实现处理方法。
    【解决方案2】:

    您可能希望实现您的过滤器,以便它们获取一个集合并返回一个过滤后的集合:

    public interface IFilter<E> {
      public Collection<E> filter(Collection<E> input);
    }
    

    通过这种方式,您可以非常简单地将过滤器链接在一起。缺点是对于大型集合来说速度较慢并且占用更多空间;但代码可读性更强。

    【讨论】:

      【解决方案3】:

      为什么不使用Bean-Query?它可以使您的代码可读。

      List<MyPOJO> result=selectBean(MyPOJO.class).where(
                                                      not(
                                                        anyOf(
                                                            value("aga",lessThan(21)),
                                                            value("age",greaterThan(50))
                                                        )
                                                      )
                                                  .executeFrom(myPojos).
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多