用于过滤项目集合的设计模式?

sha*_*kin 15 collections design-patterns filtering

想象一下典型的应用程序类型,其中包含具有不同属性的项目列表.如树视图与100个项目,每个都具有一个名称,一个等级,一个等级中最炙手可热的项-上的行星等等大概也有不少之间对多的关系,项目本期特价货品目录,或项目项目创建者之间等.

现在这个应用程序自然需要一个过滤系统 例如,我可以在不同关系中的数据之间构建具有多种条件的复杂过滤器.

编写这样一个过滤功能的设计任务应该是许多开发人员所做的事情,并且肯定必须有某种最适合该任务的设计模式.

任何人?

编辑:切换到社区维基,因为我怀疑没有任何行业de因素模式用于此.我猜这个问题太普遍了.

Mat*_* M. 6

实际指出你想要的东西有点困难,所以我会采取自己的假设.

  1. 过滤后,底层集合应保持不变
  2. 结果并不持久

一种经典的方法是使用视图.这基本上是懒惰编程,您可以在其中创建一个对象,该对象可以访问原始集合并知道要应用的过滤器,但只要不需要任何计算就不会进行任何计算.

在集合上,视图通常用迭代器实现,对于过滤,当然还有已经指出的策略模式.

例如:

Collection myCollection;
Predicate myFilter;

// Nothing is computed here
View<Predicate> myView(myCollection, myFilter);

// We iterate until we find the first item in the collection that satisfies
// the Predicate, and no more, to initialize `begin`
View<Predicate>::Iterator begin = myView.begin(), end = myView.end();
Run Code Online (Sandbox Code Playgroud)

净优势是,如果你(比方说)只需要10个第一项,那么你只需要尽可能多地应用谓词来首先找到那10个,而不是更多.

此外,没有涉及的元素的副本,即使您修改了您的视图也保证更新myCollection,尽管这可能会影响迭代器的有效性(像往常一样).

问题是(除非你实现缓存),每次都会计算结果.

如果您想要更持久的结果,那么您最好构建一个仅包含已过滤项(或对它们的引用)的新集合.此处没有一般模式,这取决于您希望如何使用"已过滤"列表.

至于策略模式建议,您通常可以使用复合模式逐块构建过滤器,然后将构建的对象作为策略传递.

复合模式特别适合表示解析表达式的结果,例如,您可能希望查看表达式树以获得想法.