Friday, 30 August 2013

Iterator Design Pattern - Implementation

🚀 Master Java Design Patterns & Software Architecture!

Subscribe to Ram N Java for clean software architecture patterns, design pattern deep dives, and production-ready implementation guides!

🔔 Subscribe to Ram N Java

Implementing the Iterator Design Pattern in Java

The Iterator Design Pattern is one of the most widely used behavioral patterns in software engineering. While the concept of stepping through elements sequentially is straightforward, creating a robust, reusable implementation requires adhering to sound design principles. Implementing the pattern correctly ensures that custom aggregate structures—such as trees, custom lists, or graph nodes—can be traversed predictably without exposing internal data structures or creating concurrent modification bugs.

Key Components & Architecture

  • The Iterator Interface: Declares core traversal operations such as hasNext(), next(), and optionally remove().
  • The Concrete Iterator: Implements the interface, maintains the internal cursor position, and directly queries the collection to retrieve items in sequential order.
  • The Aggregate / Container Interface: Defines factory methods (e.g., createIterator() or Java's iterator() via Iterable<T>) to decouple the creation of iterators from client code.
  • The Concrete Aggregate: Manages internal data storage and instantiates the concrete iterator with a reference to itself.

Implementation Best Practices

  1. Implement Standard Interfaces: Leverage Java's built-in Iterable<T> and Iterator<T> interfaces so your custom collections seamlessly integrate with enhanced for-each loops and Stream APIs.
  2. Guard Against Fail-Fast Scenarios: Track structural modifications (like a modCount variable) to detect concurrent modifications and immediately throw ConcurrentModificationException if the collection is altered outside the iterator.
  3. Encapsulate Concrete Iterators: Declare concrete iterators as private inner or package-private classes within the aggregate to protect internal structural references from external tampering.
  4. Handle Boundaries Gracefully: Ensure next() throws NoSuchElementException when called without checking hasNext(), avoiding silent failures or null pointer exceptions.

Why Proper Implementation Matters

  • Polymorphic Iteration: Clients can write uniform traversal algorithms that work identically across arrays, trees, linked nodes, or custom data structures.
  • Concurrent Traversals: Multiple clients can simultaneously iterate over the same aggregate without race conditions, since each iterator holds its own independent cursor.
  • Clean Separation of Concerns: The aggregate class stays focused strictly on data storage, while traversal mechanics remain isolated in dedicated iterator objects.

Recommended Next Videos

Continue your deep dive into behavioral patterns and collection traversal with these related guides from our channel:


Click here to watch in Youtube : https://www.youtube.com/watch?v=uRiKSJAnmeA

Click the below Image to Enlarge
Iterator Design Pattern - Implementation

















IteratorPatternDemo.Java

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class IteratorPatternDemo
{

public static void main( String[] args )
{
ArrayList<String> listOfCountries = new ArrayList<String>();
listOfCountries.add("India");
listOfCountries.add("US");
listOfCountries.add("Japan");
listOfCountries.add("France");

Iterator<String> iterator = listOfCountries.iterator();
System.out.println("Iterator type for the Datastructure ArrayList : "+iterator.toString());
System.out.println();
while( iterator.hasNext() )
{
String countryName = iterator.next();
System.out.println("Country Name : " + countryName);
}
System.out.println();
Set<String> setOfCountries = new HashSet<String>();
setOfCountries.add("India");
setOfCountries.add("US");
setOfCountries.add("Japan");
setOfCountries.add("France");
Iterator<String> iterator1 = setOfCountries.iterator();
System.out.println("Iterator type for the Datastructure HashSet : "+iterator1.toString());
System.out.println();
while( iterator1.hasNext() )
{
String countryName = iterator1.next();
System.out.println("Country Name : " + countryName);
}

}

}

Output

Iterator type for the Datastructure ArrayList : java.util.AbstractList$Itr@12dacd1

Country Name : India
Country Name : US
Country Name : Japan
Country Name : France

Iterator type for the Datastructure HashSet : java.util.HashMap$KeyIterator@30c221

Country Name : France
Country Name : US
Country Name : Japan
Country Name : India

Iterator Design Pattern - Introduction

🚀 Master Java Design Patterns & Software Architecture!

Subscribe to Ram N Java for clean software architecture patterns, design pattern deep dives, and practical engineering guides!

🔔 Subscribe to Ram N Java

Introduction to the Iterator Design Pattern

Collections are one of the most fundamental data structures in programming, whether they are represented as lists, arrays, trees, or graphs. However, if client code needs to know the exact internal structure of a collection to traverse its items, the system becomes tightly coupled and difficult to maintain. The Iterator Design Pattern is a foundational behavioral pattern that provides a standard, uniform way to access elements of an aggregate collection sequentially without exposing its underlying representation.

Core Fundamentals & Mechanics

  • Decoupled Traversal: Extracts the navigation responsibility from the collection and delegates it to a separate iterator object.
  • Uniform Client Interface: The client uses standard operations such as checking if elements remain and fetching the next element, without needing to know whether the data is backed by an array, linked nodes, or a binary tree.
  • Independent Iteration State: Because the cursor position is encapsulated inside the iterator instance rather than the collection itself, multiple clients can traverse the same collection simultaneously without conflicts.

Key Participants in the Pattern

  1. Iterator Interface: Declares the operations required for traversing elements (e.g., hasNext(), next()).
  2. Concrete Iterator: Implements the traversal interface, maintains the active cursor index, and accesses the aggregate data.
  3. Aggregate Interface: Declares a factory method (e.g., createIterator()) to supply an iterator instance.
  4. Concrete Aggregate: Holds the actual collection data and returns a new concrete iterator configured to traverse its contents.

Major Architectural Benefits

  • Single Responsibility Principle (SRP): The collection focuses strictly on managing and storing elements, while traversal algorithms remain isolated.
  • Open/Closed Principle (OCP): You can implement new collection structures or specialized traversal orders without altering existing client code.
  • Information Hiding: Internal array boundaries, pointer linkages, and private storage mechanisms remain completely encapsulated.

Recommended Next Videos

Continue your deep dive into behavioral patterns and collection traversal with these related guides from our channel:


Click here to watch in Youtube : https://www.youtube.com/watch?v=Pganyj1dVVU

Click the below Image to Enlarge
Iterator Design Pattern - Introduction
























See also:

  • Iterator Design Pattern - Implementation
  • Iterator Design Pattern - KeyPoints
  • All Design Patterns Links
  • Intercepting Filter Design Pattern - Implementation

    🚀 Level Up Your Java Architecture Skills!

    Subscribe to Ram N Java for clean code walkthroughs, design pattern implementations, and step-by-step programming guides!

    🔔 Subscribe to Ram N Java

    Practical Implementation of Intercepting Filter

    The Intercepting Filter Design Pattern is widely applied in modern web frameworks and enterprise backends to handle cross-cutting concerns cleanly. Instead of embedding security checks, request encoding, or auditing directly into your business controllers, this pattern lets you execute specialized filters in an ordered chain before reaching the final handler.

    How the Components Work Together

    • Filter Interface: Defines a standard contract (such as an execute(String request) method) that every concrete filter implements.
    • Concrete Filters: Specific implementations that handle focused tasks (e.g., an AuthenticationFilter validating credentials or a DebugFilter logging request payloads).
    • Target: The ultimate business destination or resource (such as a core service or web handler) that processes the request once all filters approve.
    • FilterChain: Maintains an ordered list of filters, executes them sequentially, and finally triggers the target.
    • FilterManager: Coordinates the filter chain setup and manages which filters attach to incoming requests.
    • Client: The caller that sends requests through the FilterManager rather than directly to the target.

    Execution Flow in Code

    1. The Client issues an incoming request.
    2. The FilterManager receives the request and initializes the FilterChain.
    3. The FilterChain invokes each registered Filter in succession (e.g., checking tokens, validating headers, logging data).
    4. Once every filter executes successfully, the chain passes control directly to the Target.

    Key Benefits for Software Design

    • Single Responsibility: Each filter class has only one job, making your codebase modular and easy to debug.
    • Dynamic Extensibility: You can plug in new filters (like rate limiting or data compression) without modifying the target resource.
    • High Reusability: Common filters can be attached to multiple handlers across different services.

    Recommended Next Videos

    Deepen your understanding of filters and servlet architecture with these related tutorials from our channel:


    Click here to watch in Youtube : https://www.youtube.com/watch?v=sWtchigtgXk

    Click the below Image to Enlarge
    Intercepting Filter Design Pattern - Implementation






















    Filter.Java

    public interface Filter
    {
    public void processRequest(String request);
    }

    AuthenticationFilter.java

    public class AuthenticationFilter implements Filter
    {

    @Override
            public void processRequest( String request )
            {
    System.out.println("Authenticating the request by AuthenticationFilter : " + request);
           
            }

    }

    LoggingFilter.java

    public class LoggingFilter implements Filter
    {
    @Override
            public void processRequest( String request )
            {
    System.out.println("Request Tracking is done by LoggingFilter : " + request);        
            }
    }

    Target.java

    public class Target
    {
    public void processRequest( String request )
    {
    System.out.println("Process the Request by Target Class: " + request);
    }
    }

    FilterChain.java

    import java.util.ArrayList;
    import java.util.List;

    public class FilterChain
    {
    private List<Filter> filters = new ArrayList<Filter>();
    private Target       target;

    public void addFilter( Filter filter )
    {
    filters.add(filter);
    }

    public void execute( String request )
    {
    for( Filter filter : filters )
    {
    filter.processRequest(request);
    }
    target.processRequest(request);
    }

    public void setTarget( Target target )
    {
    this.target = target;
    }
    }

    FilterManager.java

    public class FilterManager
    {
    FilterChain filterChain;

    public FilterManager( Target target )
    {
    filterChain = new FilterChain();
    filterChain.setTarget(target);
    }

    public void setFilter( Filter filter )
    {
    filterChain.addFilter(filter);
    }

    public void filterRequest( String request )
    {
    filterChain.execute(request);
    }
    }

    Client.java

    public class Client
    {
    FilterManager filterManager;

    public void setFilterManager( FilterManager filterManager )
    {
    this.filterManager = filterManager;
    }

    public void sendRequest( String request )
    {
    filterManager.filterRequest(request);
    }

    public static void main( String[] args )
    {
    FilterManager filterManager = new FilterManager(new Target());
    filterManager.setFilter(new AuthenticationFilter());
    filterManager.setFilter(new LoggingFilter());
    Client client = new Client();
    client.setFilterManager(filterManager);
    client.sendRequest("HOME");

    }

    }

    Output

    Authenticating the request by AuthenticationFilter : HOME
    Request Tracking is done by LoggingFilter : HOME


    Intercepting Filter Design Pattern - Class and Sequence Diagram

    🚀 Master Object-Oriented Architecture!

    Subscribe to Ram N Java for clean diagrams, enterprise design patterns, and clear step-by-step guides!

    🔔 Subscribe to Ram N Java

    Understanding the Architecture

    The Intercepting Filter Design Pattern is an architectural pattern tailored for web and enterprise applications. It intercepts incoming client requests and outgoing responses to execute critical pre-processing and post-processing tasks—such as authentication, session verification, logging, and data compression—without modifying the business logic inside the target handler.

    Class Diagram: Participants and Roles

    To design this pattern properly, let us examine the main classes and interfaces that form the backbone of the architecture:

    • Filter (Interface): Declares the abstract execution method (e.g., execute(String request)) that all concrete filters implement.
    • Concrete Filters: Specific implementations that handle individual cross-cutting concerns (e.g., AuthenticationFilter, DebugFilter, AuditFilter).
    • FilterChain: Holds an ordered sequence of filters, executes them one after another, and forwards the processed request to the final target.
    • Target: The ultimate business destination, controller, servlet, or resource requested by the client.
    • FilterManager: Coordinates the creation and lifecycle of the FilterChain, attaches the required filters, and initiates request processing.
    • Client: The requester that invokes the FilterManager to access the protected target resource.

    Sequence Diagram: Execution Flow Step-by-Step

    The sequence diagram illustrates how messages move dynamically between objects at runtime:

    1. Client Triggers Request: The client sends a request to the FilterManager.
    2. Manager Assembles Chain: The FilterManager creates or configures the FilterChain and binds the designated Target.
    3. Sequential Filter Execution: The FilterChain calls each registered filter sequentially to run pre-processing tasks (such as inspecting headers or validating credentials).
    4. Delegation to Target: Once all filters finish their tasks without errors, the chain delegates execution to the Target object.
    5. Response Lifecycle: The target generates the response, which can optionally pass through the chain in reverse order for post-processing before reaching the client.

    Key Design Benefits

    • Centralized Request Processing: Keeps common security, auditing, and transformation logic out of core business classes.
    • Loose Coupling: Filters are completely independent of one another and independent of the target resource.
    • Pluggable Components: You can add, reorder, or disable individual filters without refactoring or breaking existing business services.

    Recommended Next Videos

    Broaden your understanding of enterprise and structural patterns with these tutorials from our channel:


    Click here to watch in Youtube : https://www.youtube.com/watch?v=5MppAW_lGnQ

    Click the below Image to Enlarge
    Intercepting Filter Design Pattern - Class and Sequence Diagram

    Intercepting Filter Design Pattern - Introduction

    🚀 Master Java Enterprise Architecture!

    Subscribe to Ram N Java for beginner-friendly design pattern tutorials, clean code architectures, and step-by-step guides!

    🔔 Subscribe to Ram N Java

    Introduction to Intercepting Filter Pattern

    In modern web and enterprise applications, incoming requests often require specialized handling before reaching their primary destination. The Intercepting Filter Design Pattern is an architectural pattern designed to intercept incoming requests and outgoing responses, applying critical pre-processing and post-processing tasks seamlessly.

    Why Do We Need This Pattern?

    When multiple services or servlets need similar administrative tasks—such as verifying security credentials, tracking user activity, or compressing payloads—hardcoding those operations into each individual handler creates heavy code duplication. The Intercepting Filter pattern solves this by:

    • Isolating Cross-Cutting Concerns: Separating logging, authentication, and encryption from business controllers.
    • Enabling Modularity: Each filter focuses exclusively on one specific operational task.
    • Declarative Chaining: Multiple filters can be combined in any designated order without altering client or target code.

    How Interception Works

    Rather than connecting directly to the destination resource, client requests flow through an interception pipeline:

    1. Pre-Processing: Filters inspect headers, authenticate tokens, decrypt incoming payloads, or audit access times.
    2. Target Delegation: If all filters pass successfully, the request reaches the target resource (such as a core servlet or controller).
    3. Post-Processing: The outgoing response can pass back through the filters to perform formatting, caching, or compression before returning to the client.

    Core Architecture Participants

    • Filter: The pluggable component performing a dedicated check or transformation.
    • Filter Chain: The manager that coordinates sequential execution across registered filters.
    • Filter Manager: Creates and configures filter chains based on the incoming request route.
    • Target: The ultimate business resource handling the client request.

    Recommended Next Videos

    Continue mastering enterprise patterns with these related tutorials from our channel:


    Click here to watch in Youtube : https://www.youtube.com/watch?v=XuIa6NsQAuA

    Click the below Image to Enlarge
    Intercepting Filter Design Pattern - Introduction

    Front Controller Design Pattern - Implementation

    🚀 Master Java Architecture!

    Join our community for clear, practical coding tutorials that get you hired.

    SUBSCRIBE TO RAM N JAVA

    Implementing the Front Controller Pattern

    In software design, the Front Controller Pattern is a powerful way to manage complex web applications. By providing a single entry point for all requests, you can handle common tasks—like security and logging—in one place instead of repeating code across dozens of different files.

    1. The Core Idea

    Think of the Front Controller as a Receptionist in a large office building. Instead of guests wandering around trying to find the right room, they all talk to the receptionist first. The receptionist checks their ID (Security) and then directs them to the correct office (Dispatching).

    2. Key Best Practices

    To implement this pattern effectively, keep these three points in mind:

    • Keep it Lightweight: The controller should delegate the "heavy lifting" to other specialized classes.
    • Centralize Common Logic: Tasks like user authentication or tracking page views should happen here.
    • Use a Dispatcher: The controller should use a separate 'Dispatcher' object to figure out which view or data to return.

    3. Why Developers Love It

    For beginners, this pattern might seem like extra work at first, but it makes your application much easier to scale. When you need to add a new security feature, you only have to change it in one file rather than fifty!

    Check Out More From Ram N Java

    If you're ready to dive deeper into Java and software development, check out these related videos:



    Click the below Image to Enlarge
    Front Controller Design Pattern - Implementation - Class Diagram























    UserView.java

    public class UserView
    {
    public void show()
    {
    System.out.println("Displaying User Page");
    }
    }


    SalaryView.java

    public class SalaryView
    {
    public void show()
    {
    System.out.println("Displaying Salary Page");
    }
    }


    AccountView.java

    public class AccountView
    {
    public void show()
    {
    System.out.println("Displaying Account Page");
    }
    }

    Dispatcher.java

    public class Dispatcher
    {
    private SalaryView  salaryView;
    private UserView    userView;
    private AccountView accountView;

    public Dispatcher()
    {
    salaryView = new SalaryView();
    userView = new UserView();
    accountView = new AccountView();
    }

    public void dispatch( String request )
    {
    if( request.equalsIgnoreCase("USER") )
    {
    userView.show();
    }
    else if( request.equalsIgnoreCase("ACCOUNT") )
    {
    accountView.show();
    }
    else
    {
    salaryView.show();
    }
    }
    }


    FrontController.java

    public class FrontController
    {
    private Dispatcher dispatcher;

    public FrontController()
    {
    dispatcher = new Dispatcher();
    }

    private boolean isAuthenticUser()
    {
    //here you have to write Authentication logic
    System.out.println("User is authenticated successfully.");
    return true;
    }

    private void trackRequest( String request )
    {
    System.out.println("Page requested: " + request);
    }

    public void dispatchRequest( String request )
    {
    // log each request
    trackRequest(request);
    // authenticate the user
    if( isAuthenticUser() )
    {
    dispatcher.dispatch(request);
    }
    }
    }

    FrontControllerPatternDemo.java

    public class FrontControllerPatternDemo
    {
    public static void main( String[] args )
    {
    FrontController frontController = new FrontController();
    frontController.dispatchRequest("USER");
    System.out.println();
    frontController.dispatchRequest("ACCOUNT");
    System.out.println();
    frontController.dispatchRequest("SALARY");
    }
    }

    Output

    Page requested: USER
    User is authenticated successfully.
    Displaying User Page

    Page requested: ACCOUNT
    User is authenticated successfully.
    Displaying Account Page

    Page requested: SALARY
    User is authenticated successfully.
    Displaying Salary Page


    See also:

  • Front Controller Design Pattern - Introduction
  • Front Controller Design Pattern - Class and Sequence Diagram
  • Front Controller Design Pattern - Key Points
  • All Design Patterns Links



  • Front Controller Design Pattern - Class and Sequence Diagram

    🚀 Master Java with Ram N Java!

    Join our community of developers and simplify complex concepts today.

    SUBSCRIBE NOW

    Visualizing the Front Controller Pattern

    The Front Controller Design Pattern is a fundamental concept in Java web development. While the theory is great, understanding how it actually looks in code and how data flows through it is where the real learning happens. In this guide, we dive into the class and sequence diagrams that make this pattern work.

    1. The Class Diagram

    A class diagram shows us the "blueprint" of our application. In a Front Controller setup, you typically have three main players:

    • FrontController: The single entry point that handles every request.
    • Dispatcher: The component responsible for choosing the right view or action.
    • Views: The final pages (like JSP or HTML) that the user eventually sees.

    2. The Sequence Diagram

    If the class diagram is the blueprint, the Sequence Diagram is the movie. It shows the step-by-step movement of a request:

    1. The user sends a request to the server.
    2. The FrontController intercepts the request first.
    3. It asks the Dispatcher to find the correct view.
    4. The Dispatcher returns the view, and the controller displays it to the user.

    3. Why Use Diagrams?

    For beginners, diagrams help bridge the gap between abstract code and real-world logic. Seeing the flow of information helps you visualize where to place your security checks, logging, and data processing without making your code messy.

    Explore More Java Content

    Ready for more? Check out these other tutorials from the Ram N Java channel:



    Click the below Image to Enlarge
    Front Controller Design Pattern - Class and Sequence Diagram
























    Front Controller Design Pattern - Introduction

    🚀 Become a Pro Developer!

    Subscribe to Ram N Java for simple, powerful coding tutorials that make learning fun.

    CLICK TO SUBSCRIBE

    Why You Need the Front Controller Pattern

    When building web applications, especially in Java, managing multiple pages and requests can quickly become a mess. The Front Controller Design Pattern is the professional solution to this problem. It provides a single entry point for all incoming requests, acting as a "gatekeeper" for your entire application.

    The Single Entry Point Concept

    Imagine a large building with fifty different doors. If you wanted to check everyone's security badge, you'd need fifty guards! That's how applications work without this pattern. With the Front Controller, you have one main door. One guard handles security, logging, and directions for everyone. This makes your code much cleaner and easier to manage.

    Key Components

    • Front Controller: The initial handler that receives every request.
    • Dispatcher: The component that knows exactly which view or data to send back to the user.
    • View: The actual page the user sees at the end of the process.

    Why Beginners Should Use It

    As a beginner, using this pattern helps you learn Separation of Concerns. By keeping your request logic separate from your page content, you can change your security rules or site-wide settings in just one file instead of updating every single page on your website.

    More from Ram N Java

    Check out these other videos to continue your learning journey:



    Click the below Image to Enlarge
    Front Controller Design Pattern - Introduction

    Saturday, 24 August 2013

    Session State Design pattern


    Click here to watch in Youtube : https://www.youtube.com/watch?v=js-OlYuXRi4

    Click the below Image to Enlarge
    Session State  Design pattern















    See also:

  • All Design Patterns Links
  • Base Design Pattern


    Click here to watch in Youtube : https://www.youtube.com/watch?v=73iG2MSAY30

    Click the below Image to Enlarge
    Base Design Pattern














    See also:

  • All Design Patterns Links
  • Offline Concurrency Patterns


    Click here to watch in Youtube : https://www.youtube.com/watch?v=9UBuUDL76fI

    Click the below Image to Enlarge
    Offline Concurrency Patterns














    See also:

  • All Design Patterns Links
  • Distribution Patterns


    Click here to watch in Youtube : https://www.youtube.com/watch?v=cDgB46gx9V4

    Click the below Image to Enlarge
    Distribution Patterns














    See also:

  • All Design Patterns Links
  • Object-Relational Metadata Mapping Patterns


    Click here to watch in Youtube : https://www.youtube.com/watch?v=T7Dqys234X8

    Click the below Image to Enlarge
    Object-Relational Metadata Mapping Patterns















    See also:

  • All Design Patterns Links
  • Tutorials