C# дизайн шаблон предложения
У меня есть коллекция предметов. Из этой коллекции мне нужно искать вхождение объекта, используя ряд условий. то есть.
Поиск с использованием условия 1
Если условие 1 не выполнено, используйте условие 2
Если условие 2 не выполнено, используйте условие 3
Если условие 3 не выполнено, используйте условие 4
Каждое из этих условий состоит из нескольких фильтров.
Я ищу предложения относительно шаблона проектирования, который можно обслуживать. Примеры реализации будут оценены.
3 ответа
Похоже, цепь ответственности:
http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
В объектно-ориентированном проектировании шаблон цепочки ответственности представляет собой шаблон проектирования, состоящий из источника командных объектов и серии обрабатываемых объектов. Каждый объект обработки содержит логику, которая определяет типы объектов команд, которые он может обрабатывать; остальные передаются следующему объекту обработки в цепочке. Существует также механизм добавления новых объектов обработки в конец этой цепочки.
Не зацикливайтесь на "объектах командования". Суть шаблона CoR состоит в том, что это цепочка объектов, которые либо сами обрабатывают работу, либо передают ее следующему в цепочке.
Реализация:
public interface LinkInChain {
boolean search(final Data data, final OnFound onFound);
}
public abstract class LinkInChainBase {
final private LinkInChain nextLink;
public LinkInChainBase(final LinkInChain nextLink) {
this.nextLink = nextLink;
}
protected abstract innerSearch(final Data data, final OnFound onFound);
public boolean search(final Data data, final OnFound onFound) {
if (!innerSearch(data, onFound)) {
return nextLink.search(data, onFound);
}
}
}
public class SearchFactory {
private final LinkInChain lastLink = new LinkInChain() {
public boolean search(final Data data, final OnFound onFound) {
return false;
}
}
public LinkInChain searchChain() {
return new SearchUsingCond1(
new SearchUsingCond2(
new SearchUsingCond3(
new SearchUsingCond4(
lastLink
)
)
)
)
}
};
Такое ощущение, что Стратегия с какой-то фабрикой может привести вас на правильный путь.
Вы можете начать с реализации чего-то подобного для каждого фильтра:
public interface IFilter<T>
{
bool Matches(T itemToMatch);
}
Для подслоя фильтров (Условие 1... n) вы можете использовать составной фильтр "все", как этот; Все IFilter<T>
содержащиеся реализации должны соответствовать для композита, чтобы сказать, что он соответствует:
public class AllMatchingCompositeFilter : List<IFilter<MyClass>>, IFilter<MyClass>
{
public bool Matches(T itemToMatch)
{
return this.All(filter => filter.Matches(itemToFilter));
}
}
... и для фильтров верхнего уровня (если условие n не совпадает, проверьте условие n+1), вы можете объединить несколько AllMatchingCompositeFilter
s в "любом" фильтре, подобном этому; он выполняет каждый из своих IFilter<T>
s в том порядке, в котором они были добавлены, и возвращает true, если любой из них совпадает:
public class AnyMatchingCompositeFilter : List<IFilter<MyClass>>, IFilter<MyClass>
{
public bool Matches(T itemToMatch)
{
return this.Any(filter => filter.Matches(itemToFilter));
}
}