缓存和过滤聚合方法

发布于 2024-11-10 18:36:22 字数 1526 浏览 2 评论 0原文

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

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

选项 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
}

这些方法将检查它们的缓存,如果使用了该过滤器查询,它就会只是使用这些结果。这是有风险的,因为您可能会通过稍微不同的查询生成相同的结果集(即交换反射逻辑子句的顺序)。我觉得这意味着编码员可能会在他/她打算使用缓存时意外地没有使用缓存。

这也感觉就像我在不需要时来回传递了很多东西——大概编码器将在所有结果方法中使用单个过滤器集(当我想要结果和获胜者和获胜者时)平局状态,在任何给定时刻都可能是相同的投票过滤器)

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

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

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。我最不喜欢这个选择,但想把它扔在这里供考虑,以防有人有强烈的想法。

有人有见解吗?其他选择?

I have a Polling system. I want to be able to calculate results based on filtered subsets of votes. To do this, I'm allowing the caller to pass a subquery to my model, which is then used to select only a subset of the votes when calculating results.

The catch is that I want to cache my results, and queries are flexible to the point of being horrible keys in a cache hash. This is where I come to you: How should I pass filters into my result methods in order to strike the best balance between good code practice, reliable caching (i.e. the coder can easily understand when things are being cached), and filter flexibility.

Option 1: Suck it up and live with query hashes

pass the $voteFilter into each method so that the methods look something like this:

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
}

The methods would check their caches and if that filter query had been used, it just uses those results. This is risky because you could have the same result set generated by slightly different queries (i.e. the order of a reflective logical clause is swapped). I feel this means a coder could accidentally not be using a cache when he/she intends to.

This also feels like I'm passing a lot back and forth when I don't need to -- presumably the coder will be working with a single filter set across all of the result methods (When I want the results and the winner and the tie status, it will probably be for the same vote filter at any given moment)

Option 2: Set the filter using a separate class method

Pass the $voteFilter that is currently being used using a setFilter() method, starting a result session. This would reset the cache each time it is called and would dictate the filter used in result methods until the next time setFilter is called. Looking like this:

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
}

This option feels more elegant and I like it, but I don't know if it is bad form and is the kind of thing I'll look at in two months and say "this is horrible. Why would I have made methods without explicit parameters"

Option 3: Define a more rigid filtering technique

If I limit the ways I can filter I can create filter parameters which have no room for confusion, solving the ambiguity issues in Option 1. This limits flexibility and could result in a less understandable API. I like this choice least but wanted to throw it out here for consideration in case someone has a strong thought.

Anyone have insight? Other options?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

杀手六號 2024-11-17 18:36:22

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

class Poll {
   withFilter(filter)
   getFilter(...)
   getResults(...)
   getWinner(...)   
}

现在,withFilter 返回一个应用了给定过滤器的 Poll 对象(可能是累积的,但是正如您所注意到的,必须小心-- 例如,AST 或上下文必须是句柄或过滤器必须属于某一类限制)。返回的对象可以是一个 Poll 对象或一个缓存 Poll 对象——如果 Poll 是不可变的,那就没关系。如果缓存完全通过可达性来维护,那么这也可以处理“清理”——但这实际上取决于语言。

快乐编码。

Imagine that Poll is immutable with a signature like:

class Poll {
   withFilter(filter)
   getFilter(...)
   getResults(...)
   getWinner(...)   
}

Now, withFilter returns a Poll object that has the given filter applied (perhaps cumulative, however as you note, care must be taken -- e.g. an AST or context must be handle or filter must fall into a certain class of restrictions). The object returned can be a new Poll object or a cached Poll object -- if Poll is immutable it doesn't matter. If the cache is maintained entirely with reach-ability then this may also handle "cleanup" -- but that really depends upon language.

Happy coding.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文