Вы можете реализовать фильтры как Декораторы . Фактически, способ вызова преемника в вашем фильтре точно такой же, как у Decorator, так почему бы не реализовать шаблон полностью. Основным отличием будет то, что преемник передается в конструктор. Тогда вы сможете связать их вместе так:
Filter f3 = new Filter3();
Filter f2 = new Filter2(f3);
Filter f = new Filter1(f2);
foreach (User u in users)
{
foreach (GeoRegion r in regions)
{
f.Process(u, r, ##);
}
}
Как вы, вероятно, хорошо знаете, вы можете встроить свой метод шаблона в стратегию : один общий базовый интерфейс, абстрактный подкласс общего шаблона метода для каждого отдельного набора фильтров, а затем набор конкретных Подклассы реализации для каждого.
Трудной частью является другой набор параметров. Если вы хотите использовать новые фильтры, прозрачно смешанные со старыми, они должны иметь один и тот же интерфейс, таким образом, они все должны получить (и передать) расширенный набор всех существующих параметров, который быстро становится уродливым за счет 4- 5 параметров.
Можно было бы передать специальные параметры в конструкторе каждого фильтра и общие параметры process
, но это сложно, поскольку у вас много циклов в цикле с различными параметрами ... Если вы не можете двигаться весь вложенный цикл foreach
внутри фильтров, который затем получит users
и regions
в качестве параметров:
public class Filter
{
private UserCollection users;
private GeoRegionCollection regions;
public void Process(UserCollection users, GeoRegionCollection regions)
{
this.users = users;;
this.regions = regions;
}
public void Process()
{
foreach (User u in users)
{
foreach (GeoRegion r in regions)
{
Process(u, r, ##);
}
}
}
public void Process(User u, GeoRegion r, int countNeeded)
{
// as before
}
}
Другая возможность может состоять в том, чтобы сгруппировать эти параметры в какую-то общую структуру, которая имеет достаточную изменчивость для хранения ваших различных наборов параметров. Обычно, как правило, это будет какое-то уродливое хранилище, похожее на карту, где вам нужно искать параметры по имени, а затем понижать их до нужного типа: - (
Трудно сказать больше, не зная больше деталей ...