オブジェクトのコレクションがあります。このコレクションから、いくつかの条件を使用してオブジェクトの出現を検索する必要があります。すなわち。
条件1を使用して検索
条件1が失敗した場合は、条件2を使用します
条件2が失敗した場合は、条件3を使用します
条件3が失敗した場合は、条件4を使用します
これらの各条件は、いくつかのフィルターで構成されています。
メンテナンス可能なデザインパターンに関する提案を探しています。サンプル実装をいただければ幸いです。
オブジェクトのコレクションがあります。このコレクションから、いくつかの条件を使用してオブジェクトの出現を検索する必要があります。すなわち。
条件1を使用して検索
条件1が失敗した場合は、条件2を使用します
条件2が失敗した場合は、条件3を使用します
条件3が失敗した場合は、条件4を使用します
これらの各条件は、いくつかのフィルターで構成されています。
メンテナンス可能なデザインパターンに関する提案を探しています。サンプル実装をいただければ幸いです。
責任の連鎖のように見えます:
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>
し、いずれかが一致する場合はtrueを返します。
public class AnyMatchingCompositeFilter : List<IFilter<MyClass>>, IFilter<MyClass>
{
public bool Matches(T itemToMatch)
{
return this.Any(filter => filter.Matches(itemToFilter));
}
}