Filter Pattern in Java
The Filter Pattern in Java is a behavioural design pattern that allows you to apply filters or criteria to a collection of objects, enabling you to retrieve a subset of those objects based on specific conditions. It provides a way to decouple the filtering logic from the application's core functionality, promoting code reusability and maintainability.
Introduction to the Filter Pattern
Imagine you have a collection of objects, such as a list of products in an e-commerce application. You often need to retrieve a subset of these products based on various criteria, such as price range, category, or availability. One approach is to write filtering logic directly within the code where you need to perform filtering. However, this can lead to code duplication, making the codebase harder to maintain.
Here's a procedure for implementing the Filter Pattern in Java:
1. Determine the collection of objects you need to filter, such as a list of products or users.
2. Create a class to represent the objects in the collection, encapsulating their attributes.
3. Define a filter interface with a method for filtering the collection of objects.
4. Create concrete filter classes that implement the filter interface and provide logic for specific filtering criteria.
5. Instantiate the collection, instantiate filter objects based on criteria, and apply them to the collection to retrieve the filtered subset of objects.
Components of the Filter Pattern
Filter Interface: Defines the contract for all filters. It typically includes a method like filter(List
Concrete Filter Implementations: Classes that implement the Filter interface and provide the logic for applying specific filtering criteria. For example, you might have filters for price range, category, availability, etc.
Filter Chain (Optional): Sometimes, it's beneficial to chain multiple filters together to create more complex filtering conditions. The filter chain manages the sequence in which filters are applied and combines their results.
Client: The entity that uses the filters to retrieve the desired subset of objects from the collection. The client can configure the filters based on its requirements.
Demonstration: Filtering Products
Let's demonstrate the Filter Pattern with an example of filtering products in an e-commerce application.
FileName: ProductFilterDemo.java
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; // Define the Product class class Product { private String name; private String category; private double price; public Product(String name, String category, double price) { this.name = name; this.category = category; this.price = price; } public String getName() { return name; } public String getCategory() { return category; } public double getPrice() { return price; } @Override public String toString() { return "Product{name='" + name + "', category='" + category + "', price=" + price + "}"; } } // Define the Filter interface interface Filter{ List filter(List items); } // Define the PriceFilter class class PriceFilter implements Filter { private double minPrice; private double maxPrice; public PriceFilter(double minPrice, double maxPrice) { this.minPrice = minPrice; this.maxPrice = maxPrice; } @Override public List filter(List items) { return items.stream() .filter(product -> product.getPrice() >= minPrice && product.getPrice() <= maxPrice) .collect(Collectors.toList()); } } // Define the CategoryFilter class class CategoryFilter implements Filter { private String category; public CategoryFilter(String category) { this.category = category; } @Override public List filter(List items) { return items.stream() .filter(product -> product.getCategory().equals(category)) .collect(Collectors.toList()); } } // Demonstrate the usage of filters public class ProductFilterDemo { public static void main(String[] args) { // Create a list of products List products = new ArrayList<>(); products.add(new Product("Laptop", "Electronics", 1200.0)); products.add(new Product("Smartphone", "Electronics", 800.0)); products.add(new Product("Book", "Books", 25.0)); products.add(new Product("Chair", "Furniture", 150.0)); // Apply filters Filter priceFilter = new PriceFilter(100.0, 1000.0); Filter categoryFilter = new CategoryFilter("Electronics"); List filteredProducts = priceFilter.filter(products); filteredProducts = categoryFilter.filter(filteredProducts); // Display filtered products System.out.println("Filtered Products:"); filteredProducts.forEach(System.out::println); } }
Output:
Filtered Products: Product{name='Smartphone', category='Electronics', price=800.0}
Explanation: The Java code demonstrates the implementation of the Filter Pattern to filter a list of products based on specific criteria. Initially, a list of products is created, including items such as laptops, smartphones, books, and chairs. Two filters are then applied: a PriceFilter to include products within a price range of $100 to $1000, and a CategoryFilter to include only products in the "Electronics" category. Finally, the filtered products are displayed, showing only the products that meet both criteria.