Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 过滤项目集合的设计模式?_Design Patterns_Collections_Filtering - Fatal编程技术网

Design patterns 过滤项目集合的设计模式?

Design patterns 过滤项目集合的设计模式?,design-patterns,collections,filtering,Design Patterns,Collections,Filtering,想象一下典型的应用程序类型,其中有一个具有不同属性的项目列表。例如,一个包含100个项目的树状视图,每个项目都有一个名称、评级、全球最热门项目的排名等。项目和项目目录之间,或项目和项目创建者之间可能存在多对多关系等 现在这个应用程序自然需要一个过滤系统。例如,我可以在不同关系的数据之间构建具有各种条件的复杂过滤器 编写这样一个过滤特性的设计任务应该是许多开发人员都做过的,而且肯定有某种设计模式最适合这个任务 有人吗 编辑:切换到社区维基,因为我怀疑没有任何行业去因子模式用于此。我猜这个问题的表述

想象一下典型的应用程序类型,其中有一个具有不同属性的项目列表。例如,一个包含100个项目的树状视图,每个项目都有一个名称、评级、全球最热门项目的排名等。项目和项目目录之间,或项目和项目创建者之间可能存在多对多关系等

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

编写这样一个过滤特性的设计任务应该是许多开发人员都做过的,而且肯定有某种设计模式最适合这个任务

有人吗


编辑:切换到社区维基,因为我怀疑没有任何行业去因子模式用于此。我猜这个问题的表述过于笼统。

如果这些关系可以表示为RDF和OWL,那么您可以使用带有SPARQL端点的工具(如Jena)或推理器(如Pellet)。但如果没有更多细节,就不清楚这是否是最好的方法

我不知道它的设计模式,但你可以看看一些排序方法,如果你能解释其中的一些方法以及为什么不喜欢它们作为例子,那会很有帮助

例如,LINQ有一种很好的排序方法,使用表达式树

您还可以查看用函数式语言完成的排序,在这里您可以传递函数来实际执行排序,而不是硬编码任何特定的排序


如果您使用的是javascript之类的工具,则可以动态创建排序函数。

您正在寻找一个可以使用SQL的关系数据库。您可以建立一个完整的数据库并从应用程序连接到它,也可以在完整数据库和直接对象之间执行某些操作。例如,在Java中,您可以使用诸如HSQLDB/JavaDB之类的内存中数据库,并使用该数据库的功能。您还可以使用它,它将允许您在SQL中直接对对象进行操作,而无需使用数据库


或者,如果你想自己编程,你可以先保存两份数据副本。一个是完整的数据集,另一个是过滤后的数据视图。然后,通过对数据进行排序并保持其在已排序列表中的位置,为每个列的数据创建一个索引。相同的设置适用于过滤器匹配。如果某个内容与列的筛选器匹配,则为其指定1,如果不匹配,则为0。然后,当有人切换排序顺序时,您将数据从完整列表复制到视图列表中,或者当用户更改过滤器信息时,您将只获取具有匹配项的数据

我喜欢带谓词of的过滤器,如果我不能使用它,我会实现类似的东西。您可能希望查看类似的问题以了解实现示例。这个实现是用Java实现的,但是,你会看到它的模式。

要真正指出你想要的东西有点困难,所以我将采用我自己的假设

  • 筛选后,基础集合应保持不变
  • 结果不是持久的
  • 经典的方法是使用视图。这基本上是惰性编程,您可以创建一个对象,该对象可以访问原始集合并知道要应用的过滤器,但只要不需要任何计算,就不会进行任何计算

    在集合上,视图通常使用迭代器来实现,当然,对于过滤,正如前面所指出的策略模式

    例如:

    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();
    
    Collection;
    谓词myFilter;
    //这里没有计算任何东西
    查看myView(myCollection,myFilter);
    //我们迭代,直到在集合中找到满足
    //谓词,不再是,初始化'begin'`
    视图::迭代器begin=myView.begin(),end=myView.end();
    
    净优势在于,如果您(比如)只需要前10项,那么您将只应用谓词来查找前10项,而不需要更多

    此外,所涉及的元素没有副本,即使您修改了
    myCollection
    ,您的视图也会得到更新,尽管这可能会影响迭代器的有效性(通常)

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

    如果希望得到更持久的结果,那么最好构建一个只包含筛选项(或对它们的引用)的新集合。这里没有通用模式,因为它取决于您希望如何使用“过滤”列表

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

    复合模式特别适合于表示解析表达式的结果。例如,您可能希望查看表达式树以了解情况。

    查看是否可以帮助您。
    基于规范模式

    战略模式可能是一个很好的起点。非常有趣。詹姆斯·布莱克(James Black)也指出,这似乎是一种策略模式。任何时候,只要你考虑到算法的变化,以及如何对算法进行排序(定义松散),策略模式就是逻辑解决方案,但是,实现方式是有争议的。我喜欢使用SQL表达式作为过滤机制基础的想法。否则,我觉得这种方法将禁止我将数据库抽象为匿名和可互换的存储层。如果我错了,请纠正我。我非常喜欢将复合模式和战略模式相结合的想法,谢谢!