フィルターパターンの基本構造
フィルターパターンは、リクエスト処理やデータ変換において、各処理を独立したフィルターとして実装し、チェーン形式で処理をつなぎ合わせるデザインパターンです。この方式により、各フィルター間の結合度を低く保ちつつ、柔軟な拡張性を持たせることができます。
以下は、フィルターインターフェースとその実装クラス、チェーン構造を管理するクラスを用いたサンプルコードです。
フィルターインターフェース
public interface DataFilter {
void process(List<String> dataList, FilterChain chain);
}
具体的なフィルター実装
public class EmptyCheckFilter implements DataFilter {
@Override
public void process(List<String> dataList, FilterChain chain) {
if (dataList == null || dataList.isEmpty()) {
System.out.println("データが空です。");
return;
}
System.out.println("空チェックフィルターを通過しました。");
chain.process(dataList);
}
}
public class LoggingFilter implements DataFilter {
@Override
public void process(List<String> dataList, FilterChain chain) {
System.out.println("現在のデータ数: " + dataList.size());
System.out.print("データ内容: ");
dataList.forEach(data -> System.out.print(data + " "));
System.out.println();
chain.process(dataList);
}
}
フィルターチェーンの構造
public class FilterChain {
private DataFilter filter;
private FilterChain nextChain;
public FilterChain(DataFilter filter, FilterChain next) {
this.filter = filter;
this.nextChain = next;
}
public void process(List<String> dataList) {
if (filter != null) {
filter.process(dataList, nextChain);
}
}
}
テストコードと実行例
public class FilterTest {
public static void main(String[] args) {
List<String> dataList = new ArrayList<>();
dataList.add("テストデータ1");
dataList.add("テストデータ2");
DataFilter emptyCheck = new EmptyCheckFilter();
DataFilter logger = new LoggingFilter();
FilterChain chain = new FilterChain(emptyCheck, new FilterChain(logger, null));
chain.process(dataList);
}
}
上記のコードを実行すると、以下の出力が得られます:
空チェックフィルターを通過しました。
現在のデータ数: 2
データ内容: テストデータ1 テストデータ2
まとめ
フィルターパターンを用いることで、各フィルターを独立してテスト可能にし、処理フローの拡張性を高めることができます。この設計は、リクエストの前処理やデータ変換のシナリオに適しています。