想象一下典型的应用程序类型,其中包含具有不同属性的项目列表。例如。一个包含100个项目的树视图,每个项目都有一个名称,一个评级,一个排名最热门的项目在这个星球上< / em>等。项目和项目目录之间或项目和之间也存在多对多关系项目创建者等等。
现在这个应用程序自然需要一个过滤系统。例如。我可以在不同关系中的数据之间构建具有多种条件的复杂过滤器。
编写这样一个过滤功能的设计任务应该是许多开发人员所做的事情,肯定必须有某种最适合该任务的设计模式。
任何?
编辑:切换到社区维基,因为我怀疑没有任何行业因素模式用于此。我猜这个问题太普遍了。
答案 0 :(得分:6)
实际指出你想要的东西有点困难,所以我会采取自己的假设。
一种经典的方法是使用观点。这基本上是延迟编程,您可以在其中创建一个对象,该对象可以访问原始集合并知道要应用的过滤器,但只要不需要任何计算就不会进行任何计算。
在集合上,视图通常使用迭代器实现,对于过滤,当然还有已经指出的策略模式。
例如:
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();
净优势是,如果你(比方说)只需要10个第一项,那么你只需要尽可能多地应用谓词来首先找到那10个,而不是更多。
此外,没有涉及的元素的副本,即使您修改myCollection
,也可以保证更新您的视图,尽管这可能会影响迭代器的有效性(像往常一样)。
问题是(除非你实现缓存),每次都会计算结果。
如果您想要更持久的结果,那么您最好构建一个仅包含过滤项(或对它们的引用)的新集合。此处没有一般模式,这取决于您希望如何使用“已过滤”列表。
对于建议的策略模式,您通常可以使用复合模式逐块构建过滤器,然后将构建的对象作为策略传递。
复合模式特别适合表示解析表达式的结果,例如,您可能希望查看表达式树以获得想法。
答案 1 :(得分:1)
我不知道它的设计模式,但你可以看看为排序做的一些方法,如果你解释了其中的一些以及为什么你不喜欢它们会很有帮助举个例子。
例如,使用表达式树,LINQ有一种很好的排序方式。
您还可以查看在函数式语言中完成的排序,您可以在其中传递函数以实际进行排序,而不是对任何特定排序进行硬编码。
如果您使用的是javascript之类的东西,则可以即时创建排序功能。
答案 2 :(得分:1)
您正在寻找可以使用SQL的关系数据库。您可以站起来并从应用程序连接到它,或者您可以在完整数据库和直接对象之间执行某些操作。例如,在Java中,您可以使用内存数据库(如HSQLDB / JavaDB)并使用其中的特性。您还可以使用JoSQL,它可以直接在您的对象上运行SQL而无需数据库。
或者,如果您想自己编程,那么首先要保留2份数据。一个是您的全套数据,另一个是过滤后的数据视图。然后,您将通过对数据进行排序并在排序列表中保持其位置,为每列创建数据索引。相同的设置适用于过滤器匹配。如果某些内容与列的过滤器匹配,请将其设为1,否则为0。然后当有人切换排序顺序时,您将数据从完整列表复制到视图列表中,或者当更改过滤器信息时,您只会获取匹配的数据。
答案 3 :(得分:1)
我喜欢使用Google Collections的谓词的过滤器,如果我不能使用它,我会实现非常相似的东西。对于实现示例,您可能需要检查this answer类似的问题。实现是在Java中,但是,你会看到模式。
答案 4 :(得分:0)
如果这些关系可以表示为RDF和OWL,则可以使用具有SPARQL端点的工具(例如Jena)或推理器(例如Pellet)。但没有更多细节,目前尚不清楚这是最好的方法。
答案 5 :(得分:0)
查看http://en.wikipedia.org/wiki/Criteria_Pattern是否可以为您提供帮助。 基于规范模式