# Interface MaterialStore

All Known Subinterfaces:
  `ModernMaterialStore`

All Known Implementing Classes:
  `ConcurrentMaterialStore`, `MaterialStoreImpl`, `ModernConcurrentMaterialStore`

public interface MaterialStore
Interface defining operations for a polymorphic material store that demonstrates interface segregation and dependency inversion principles. Compare to `BookstoreAPI`, this interface is extensible to other types of materials.

The Interface Segregation Principle (ISP) states that clients should not be forced to depend on interfaces they do not use. In practice, this means designing smaller, more focused interfaces rather than large, monolithic ones. For example, instead of creating a single Machine interface with methods like print(), scan(), and fax(), which every implementation must support, ISP encourages splitting these into multiple role-specific interfaces (Printer, Scanner, FaxMachine). This ensures that implementing classes only provide the functionality relevant to them, leading to higher cohesion, reduced coupling, and easier maintenance. ISP directly combats the rigidity and fragility that arise when changes in unused methods propagate across unrelated parts of the system.

The Dependency Inversion Principle (DIP) requires that high-level modules depend on abstractions, not concrete implementations. Instead of having business logic directly tied to low-level details (like a specific database driver or logging mechanism), DIP advocates for using interfaces or abstract classes as boundaries. For instance, a PaymentService should rely on a PaymentProcessor interface rather than a hardcoded StripeProcessor. This allows developers to substitute implementations without altering higher-level policies, supporting testability, scalability, and adaptability to new technologies. By inverting the dependency direction, DIP ensures that both high- and low-level modules evolve independently, fostering loosely coupled, extensible architectures.

This interface extends the concept of a bookstore to handle various types of materials using polymorphism.

Since:
  2024-09-15
Version:
  2.0
Author:
  Navid Mohaghegh

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Interface
  Description
  `static class`
  `MaterialStore.InventoryStats`
  Statistics class for inventory analysis.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `addMaterial(Material material)`
  Adds a material to the store inventory.
  `void`
  `clearInventory()`
  Clears all materials from the store.
  `List<Material>`
  `filterMaterials(Predicate<Material> predicate)`
  Filters materials by a custom predicate.
  `List<Material>`
  `findByCreators(String... creators)`
  Finds materials by multiple creators (OR condition).
  `Optional<Material>`
  `findById(String id)`
  Finds a material by its ID.
  `List<Material>`
  `findRecentMaterials(int years)`
  Finds materials published in the last N years.
  `List<Material>`
  `findWithPredicate(Predicate<Material> condition)`
  Finds materials with custom filtering using predicate.
  `List<Material>`
  `getAllMaterials()`
  Gets all materials (unsorted).
  `List<Material>`
  `getAllMaterialsSorted()`
  Gets all materials sorted by title.
  `MaterialStore.InventoryStats`
  `getInventoryStats()`
  Gets inventory statistics.
  `List<Material>`
  `getMaterialsByPriceRange(double minPrice, double maxPrice)`
  Gets materials within a price range.
  `List<Material>`
  `getMaterialsByType(Material.MaterialType type)`
  Gets all materials of a specific type.
  `List<Material>`
  `getMaterialsByYear(int year)`
  Gets materials published/released in a specific year.
  `List<Media>`
  `getMediaMaterials()`
  Gets all materials that implement the Media interface.
  `List<Material>`
  `getSorted(Comparator<Material> comparator)`
  Gets materials sorted by custom comparator.
  `double`
  `getTotalDiscountedValue()`
  Calculates total discounted inventory value.
  `double`
  `getTotalInventoryValue()`
  Calculates total inventory value.
  `boolean`
  `isEmpty()`
  Checks if the inventory is empty.
  `Optional<Material>`
  `removeMaterial(String id)`
  Removes a material by its ID.
  `List<Material>`
  `searchByCreator(String creator)`
  Searches materials by creator (author/director/publisher).
  `List<Material>`
  `searchByTitle(String title)`
  Searches materials by title (case-insensitive partial match).
  `int`
  `size()`
  Gets the number of materials in inventory.

- ## Method Details

  - ### addMaterial

    boolean addMaterial(Material material)
    Adds a material to the store inventory.
    Parameters:
      `material` - the material to add
    Returns:
      true if added successfully, false if duplicate ID

  - ### removeMaterial

    Optional<Material> removeMaterial(String id)
    Removes a material by its ID.
    Parameters:
      `id` - the material ID
    Returns:
      the removed material, or Optional.empty() if not found

  - ### findById

    Optional<Material> findById(String id)
    Finds a material by its ID.
    Parameters:
      `id` - the material ID
    Returns:
      the material, or Optional.empty() if not found

  - ### searchByTitle

    List<Material> searchByTitle(String title)
    Searches materials by title (case-insensitive partial match).
    Parameters:
      `title` - the title to search for
    Returns:
      list of matching materials

  - ### searchByCreator

    List<Material> searchByCreator(String creator)
    Searches materials by creator (author/director/publisher).
    Parameters:
      `creator` - the creator name
    Returns:
      list of matching materials

  - ### getMaterialsByType

    List<Material> getMaterialsByType(Material.MaterialType type)
    Gets all materials of a specific type. Demonstrates polymorphic filtering.
    Parameters:
      `type` - the material type
    Returns:
      list of materials of the specified type

  - ### getMediaMaterials

    List<Media> getMediaMaterials()
    Gets all materials that implement the Media interface. Demonstrates interface-based polymorphism.
    Returns:
      list of media materials

  - ### filterMaterials

    List<Material> filterMaterials(Predicate<Material> predicate)
    Filters materials by a custom predicate. Demonstrates functional programming with polymorphism.
    Parameters:
      `predicate` - the filter condition
    Returns:
      filtered list of materials

  - ### findRecentMaterials

    List<Material> findRecentMaterials(int years)
    Finds materials published in the last N years.
    Parameters:
      `years` - the number of years to look back
    Returns:
      list of recent materials

  - ### findByCreators

    List<Material> findByCreators(String... creators)
    Finds materials by multiple creators (OR condition).
    Parameters:
      `creators` - the creator names to search for
    Returns:
      list of materials by any of the specified creators

  - ### findWithPredicate

    List<Material> findWithPredicate(Predicate<Material> condition)
    Finds materials with custom filtering using predicate.
    Parameters:
      `condition` - the filter condition
    Returns:
      filtered list of materials

  - ### getSorted

    List<Material> getSorted(Comparator<Material> comparator)
    Gets materials sorted by custom comparator.
    Parameters:
      `comparator` - the sorting comparator
    Returns:
      sorted list of materials

  - ### getMaterialsByPriceRange

    List<Material> getMaterialsByPriceRange(double minPrice, double maxPrice)
    Gets materials within a price range.
    Parameters:
      `minPrice` - minimum price (inclusive)
      `maxPrice` - maximum price (inclusive)
    Returns:
      list of materials in price range

  - ### getMaterialsByYear

    List<Material> getMaterialsByYear(int year)
    Gets materials published/released in a specific year.
    Parameters:
      `year` - the year
    Returns:
      list of materials from that year

  - ### getAllMaterialsSorted

    List<Material> getAllMaterialsSorted()
    Gets all materials sorted by title.
    Returns:
      sorted list of all materials

  - ### getAllMaterials

    List<Material> getAllMaterials()
    Gets all materials (unsorted).
    Returns:
      list of all materials

  - ### getTotalInventoryValue

    double getTotalInventoryValue()
    Calculates total inventory value.
    Returns:
      sum of all material prices

  - ### getTotalDiscountedValue

    double getTotalDiscountedValue()
    Calculates total discounted inventory value. Uses polymorphic discount calculation.
    Returns:
      sum of all discounted prices

  - ### getInventoryStats

    MaterialStore.InventoryStats getInventoryStats()
    Gets inventory statistics.
    Returns:
      statistics object with counts and averages

  - ### clearInventory

    void clearInventory()
    Clears all materials from the store.

  - ### size

    int size()
    Gets the number of materials in inventory.
    Returns:
      material count

  - ### isEmpty

    boolean isEmpty()
    Checks if the inventory is empty.
    Returns:
      true if no materials in inventory