C#设计模式建议

时间:2012-11-30 10:31:39

标签: design-patterns

我有一组对象。在这个集合中,我需要使用许多条件搜索对象的出现。即

使用条件1搜索

如果条件1失败,请使用条件2

如果条件2失败,请使用条件3

如果条件3失败,请使用条件4

这些条件中的每一个都包含许多过滤器。

我正在寻找有关可维护的设计模式的建议。示例实现将不胜感激。

3 个答案:

答案 0 :(得分: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
          )
        )
      )
    )
  }
};

答案 1 :(得分:0)

感觉像某种工厂的策略可能会让你走上正确的道路。

答案 2 :(得分:0)

你可以从每个过滤器的实现开始:

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,如下所示;它按照添加的顺序执行每个IFilter<T>,如果其中任何一个匹配则返回true:

public class AnyMatchingCompositeFilter : List<IFilter<MyClass>>, IFilter<MyClass>
{
    public bool Matches(T itemToMatch)
    {
        return this.Any(filter => filter.Matches(itemToFilter));
    }
}