Кэшированные и отфильтрованные методы агрегации - PullRequest
0 голосов
/ 28 мая 2011

У меня есть система опросов. Я хочу иметь возможность рассчитывать результаты на основе отфильтрованных подмножеств голосов. Для этого я позволяю вызывающей стороне передать подзапрос моей модели, которая затем используется для выбора только подмножества голосов при расчете результатов.

Проблема в том, что я хочу кешировать свои результаты, и запросы гибки до такой степени, что становятся ужасными ключами в хэше кеша. Вот где я прихожу к вам: как я должен передать фильтры в мои методы результата, чтобы найти наилучший баланс между хорошей практикой кода, надежным кэшированием (т.е. кодер может легко понять, когда что-то кэшируется) и гибкостью фильтра.

Вариант 1: смириться и жить с хэшами запросов

передайте $ voiceFilter в каждый метод, чтобы методы выглядели примерно так:

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: установить фильтр, используя отдельный метод класса

Передайте $ voiceFilter, который в данный момент используется, с помощью метода setFilter (), начиная сеанс с результатами. Это будет сбрасывать кэш каждый раз, когда он вызывается, и будет диктовать фильтр, используемый в методах результата, до следующего вызова 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. Мне меньше всего нравится этот выбор, но я хотел выкинуть его на рассмотрение, если у кого-то есть сильная мысль.

У кого-нибудь есть понимание? Другие варианты?

1 Ответ

1 голос
/ 28 мая 2011

Представьте себе, что Poll является неизменным с такой подписью, как:

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

Теперь withFilter возвращает объект Poll, к которому применен данный фильтр (возможно, накопительный, однако, как вы заметили, необходимо соблюдать осторожность - например, AST или контекст должны быть обработаны, или фильтр должен попадать в определенный класс ограничения). Возвращаемый объект может быть новым объектом опроса или кэшированным объектом опроса - если опрос неизменен, это не имеет значения. Если кеш поддерживается полностью с помощью достижимости, то это также может обрабатывать «очистку», но это действительно зависит от языка.

Удачного кодирования.

...