3

I have a collection of objects. Out of this collection I need to search for an occurrence of an object using a number of conditions. ie.

Search using Condition 1

If Condition 1 Fails use Condition 2

If Condition 2 Fails use Condition 3

If Condition 3 Fails use Condition 4

Each of these conditions consists of a number of filters.

I'm looking for suggestions with regards to a design pattern that's maintainable. Sample implementations will be appreciated.

ntombela
  • 1,357
  • 2
  • 19
  • 31
  • 1
    Your description is rather vague - a code example (even pseudo-code) would be much more helpful in understanding what you mean. – Oded Nov 30 '12 at 10:34

3 Answers3

3

It looks like Chain of Responsibility:

http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

In Object Oriented Design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.

Don't get hung up too much on the "command objects" thing. The core of CoR pattern is that it's a chain of objects that either handle the work themselves, or pass it on to the next one in the chain.

Implementation:

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
          )
        )
      )
    )
  }
};
Anders Johansen
  • 10,165
  • 7
  • 35
  • 52
0

It feels like a Strategy with a factory of some kind might start you on the right road.

David Osborne
  • 6,436
  • 1
  • 21
  • 35
0

You could start with implementations of something like this for each filter:

public interface IFilter<T>
{
    bool Matches(T itemToMatch);
}

For the sub-layer of filters (Condition 1...n) you could use a Composite 'all' filter like this; all of the IFilter<T> implementations contained have to match for the composite to say it matches:

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

...and for the top-level of filters (if Condition n doesn't match check Condition n+1) you could combine multiple AllMatchingCompositeFilters in an 'any' filter like this; it executes each of its IFilter<T>s in the order they were added and returns true if any of them match:

public class AnyMatchingCompositeFilter : List<IFilter<MyClass>>, IFilter<MyClass>
{
    public bool Matches(T itemToMatch)
    {
        return this.Any(filter => filter.Matches(itemToFilter));
    }
}
Steve Wilkes
  • 7,085
  • 3
  • 29
  • 32