Caching 缓存和筛选聚合方法

Caching 缓存和筛选聚合方法,caching,class-design,filtering,aggregation,Caching,Class Design,Filtering,Aggregation,我有一个投票系统。我希望能够根据过滤后的投票子集计算结果。为此,我允许调用者将子查询传递给我的模型,然后在计算结果时使用该子查询仅选择投票的子集 问题是我想缓存我的结果,而查询非常灵活,以至于在缓存哈希中成为可怕的键。这就是我要告诉你们的:我应该如何将过滤器传递到我的结果方法中,以便在良好的代码实践、可靠的缓存(即,当缓存内容时,程序员可以轻松理解)和过滤器灵活性之间取得最佳平衡 选项1:接受它并与查询哈希一起生活 将$voteFilter传递到每个方法中,使这些方法如下所示: class Po

我有一个投票系统。我希望能够根据过滤后的投票子集计算结果。为此,我允许调用者将子查询传递给我的模型,然后在计算结果时使用该子查询仅选择投票的子集

问题是我想缓存我的结果,而查询非常灵活,以至于在缓存哈希中成为可怕的键。这就是我要告诉你们的:我应该如何将过滤器传递到我的结果方法中,以便在良好的代码实践、可靠的缓存(即,当缓存内容时,程序员可以轻松理解)和过滤器灵活性之间取得最佳平衡

选项1:接受它并与查询哈希一起生活

将$voteFilter传递到每个方法中,使这些方法如下所示:

class Poll {
     getResults($voteFilter) {...} // Returns the poll results for passed filter
     getWinner($voteFilter) {...}  // Returns the winning result for passed filter
     isTie($voteFilter) {...}  // Returns tie status for passed filter
}
class Poll {
     setVoteFilter($voteFilter) {...} // Clears cache and sets vote filter
     getResults() {...} // Returns the poll results for current filter
     getWinner() {...}  // Returns the winning result for current filter
     isTie() {...}  // Returns tie status for current filter
}
这些方法将检查它们的缓存,如果使用了过滤器查询,则只使用这些结果。这是有风险的,因为您可能会通过稍微不同的查询生成相同的结果集(即,反射逻辑子句的顺序被交换)。我觉得这意味着编码人员可能无意中没有使用缓存

这也让人觉得我在不需要的时候来回传递了很多信息——大概编码人员将使用一个过滤器集来处理所有结果方法(当我想要结果、获胜者和平局状态时,可能在任何给定时刻都是针对同一个投票过滤器)

选项2:使用单独的类方法设置过滤器

通过setFilter()方法传递当前正在使用的$voteFilter,启动结果会话。这将在每次调用缓存时重置缓存,并指示结果方法中使用的过滤器,直到下次调用setFilter为止。看起来像这样:

class Poll {
     getResults($voteFilter) {...} // Returns the poll results for passed filter
     getWinner($voteFilter) {...}  // Returns the winning result for passed filter
     isTie($voteFilter) {...}  // Returns tie status for passed filter
}
class Poll {
     setVoteFilter($voteFilter) {...} // Clears cache and sets vote filter
     getResults() {...} // Returns the poll results for current filter
     getWinner() {...}  // Returns the winning result for current filter
     isTie() {...}  // Returns tie status for current filter
}
这个选项感觉更优雅,我也很喜欢,但我不知道它的形式是否糟糕,我会在两个月后看到它,并说“这太可怕了。我为什么要创建没有显式参数的方法?”

选项3:定义更严格的过滤技术

如果我限制过滤的方式,我可以创建没有混淆余地的过滤参数,解决选项1中的模糊问题。这限制了灵活性,并可能导致不易理解的API。我最不喜欢这个选择,但我想把它扔到这里考虑一下,以防有人有强烈的想法


有人有洞察力吗?其他选项?

想象一下,
Poll
是不可变的,签名如下:

class Poll {
   withFilter(filter)
   getFilter(...)
   getResults(...)
   getWinner(...)   
}
现在,
withFilter
返回一个已应用给定筛选器的轮询对象(可能是累积的,但正如您所注意的,必须小心--例如,必须处理AST或上下文,或者筛选器必须属于某类限制)。返回的对象可以是新的Poll对象或缓存的Poll对象——如果Poll是不可变的,则无所谓。如果缓存完全使用reach功能维护,那么这也可以处理“清理”——但这实际上取决于语言

快乐编码