DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Object Relational Behavioral Design Patterns in Java
  • Distribution Design Patterns in Java - Data Transfer Object (DTO) And Remote Facade Design Patterns
  • Context Object Design Pattern in Java: Introduction and Key Points
  • Java: Object Pool Design Pattern

Trending

  • Agentic AI for Automated Application Security and Vulnerability Management
  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • AI's Dilemma: When to Retrain and When to Unlearn?
  • Artificial Intelligence, Real Consequences: Balancing Good vs Evil AI [Infographic]
  1. DZone
  2. Coding
  3. Languages
  4. Using the Chain of Responsibility Design Pattern in Java

Using the Chain of Responsibility Design Pattern in Java

By 
Brijesh Saxena user avatar
Brijesh Saxena
DZone Core CORE ·
Nov. 02, 20 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
20.9K Views

Join the DZone community and get the full member experience.

Join For Free

Here, I am with another article on design patterns — Chain of Responsibility. This article will also conclude explanation of all basic design patterns.  Please visit my profile to find the other basic design patterns for reference.

Chain of Responsibility Design Pattern

  • The Chain of Responsibility Design Pattern is one of the Gang of Four design patterns which creates a chain of receiver objects for a request.
  • The Chain of Responsibility pattern is a behavioral pattern which is used to avoid coupling the sender of the request to the receiver and gives more than one receiver object the opportunity to handle the request.
  • As per Gang of Four design patterns, the Chain of Responsibility pattern is defined as:

"Gives more than one object an opportunity to handle a request by linking receiving objects together."

  • The Chain of Responsibility pattern allows a number of classes to attempt to handle a request independently.
  • The Receiver objects of the requests are free from the order and can be use in any order for processing.
  • This pattern decouples sender and receiver objects based on type of request.
  • This pattern defines a chain of receiver objects having the responsibility, depending on run-time conditions, to either handle a request or forward it to the next receiver on the chain.
  • This pattern helps us avoiding coupling of sender and receiver objects of a requests and allows us to have more than one receiver as well for the request.
  • ATM withdrawal using different currency notes is one of the great example of Chain of Responsibility pattern.
  • Using different types of Loggers in our software is another example of the pattern.
  • A call to technical support at different level of discussion is also a good example.

chain of responsibility design pattern

ATM Money Dispenser Using Chain of Responsibility Design Pattern

Let's define a class to hold the amount to withdraw first. Here's the code for PaperCurrency class:

Java
x
21
 
1
package org.trishinfotech.responsibility;
2

          
3
public class PaperCurrency {
4
    
5
    protected int amount;
6

          
7
    public PaperCurrency(int amount) {
8
        super();
9
        this.amount = amount;
10
    }
11

          
12
    public int getAmount() {
13
        return amount;
14
    }
15

          
16
    public void setAmount(int amount) {
17
        this.amount = amount;
18
    }
19
    
20
}
21

          


Now lets define a dispenser abstract class with two main purpose:

  • Process the dispense for a specific face-value of currency note.
  • Go to another dispenser for processing smaller face value of currency note.  

Here's the code for PaperCurrencyDispenser abstract class:

Java
xxxxxxxxxx
1
14
 
1
package org.trishinfotech.responsibility;
2

          
3
public abstract class PaperCurrencyDispenser {
4

          
5
    protected PaperCurrencyDispenser nextDispenser;
6

          
7
    public void setNextDispenser(PaperCurrencyDispenser nextDispenser) {
8
        this.nextDispenser = nextDispenser;
9
    }
10

          
11
    public abstract void dispense(PaperCurrency currency);
12

          
13
}


Here's the code for HundredDispenser class:

Java
xxxxxxxxxx
1
26
 
1
package org.trishinfotech.responsibility;
2

          
3
public class HundredDispenser extends PaperCurrencyDispenser {
4

          
5
    public HundredDispenser() {
6
        super();
7
    }
8

          
9
    @Override
10
    public void dispense(PaperCurrency currency) {
11
        if (currency != null) {
12
            int amount = currency.getAmount();
13
            int remainder = amount;
14
            if (amount >= 100) {
15
                int count = amount / 100;
16
                remainder = amount % 100;
17
                System.out.printf("Dispensing '%d' 100$ currency note.\n", count);
18
            }
19
            if (remainder > 0 && this.nextDispenser != null) {
20
                this.nextDispenser.dispense(new PaperCurrency(remainder));
21
            }
22
        }
23
    }
24

          
25
}


Here's the code for FiftyDispenser class:

Java
 
xxxxxxxxxx
1
26
 
1
package org.trishinfotech.responsibility;
2

          
3
public class FiftyDispenser extends PaperCurrencyDispenser {
4

          
5
    public FiftyDispenser() {
6
        super();
7
    }
8

          
9
    @Override
10
    public void dispense(PaperCurrency currency) {
11
        if (currency != null) {
12
            int amount = currency.getAmount();
13
            int remainder = amount;
14
            if (amount >= 50) {
15
                int count = amount / 50;
16
                remainder = amount % 50;
17
                System.out.printf("Dispensing '%d' 50$ currency note.\n", count);
18
            }
19
            if (remainder > 0 && this.nextDispenser != null) {
20
                this.nextDispenser.dispense(new PaperCurrency(remainder));
21
            }
22
        }
23
    }
24

          
25
}


Here's the code for TwentyDispenser class:

Java
 
xxxxxxxxxx
1
26
 
1
package org.trishinfotech.responsibility;
2

          
3
public class TwentyDispenser extends PaperCurrencyDispenser {
4

          
5
    public TwentyDispenser() {
6
        super();
7
    }
8

          
9
    @Override
10
    public void dispense(PaperCurrency currency) {
11
        if (currency != null) {
12
            int amount = currency.getAmount();
13
            int remainder = amount;
14
            if (amount >= 20) {
15
                int count = amount / 20;
16
                remainder = amount % 20;
17
                System.out.printf("Dispensing '%d' 20$ currency note.\n", count);
18
            }
19
            if (remainder > 0 && this.nextDispenser != null) {
20
                this.nextDispenser.dispense(new PaperCurrency(remainder));
21
            }
22
        }
23
    }
24

          
25
}


Here's the code for TenDispenser class:

Java
 
xxxxxxxxxx
1
26
 
1
package org.trishinfotech.responsibility;
2

          
3
public class TenDispenser extends PaperCurrencyDispenser {
4

          
5
    public TenDispenser() {
6
        super();
7
    }
8

          
9
    @Override
10
    public void dispense(PaperCurrency currency) {
11
        if (currency != null) {
12
            int amount = currency.getAmount();
13
            int remainder = amount;
14
            if (amount >= 10) {
15
                int count = amount / 10;
16
                remainder = amount % 10;
17
                System.out.printf("Dispensing '%d' 10$ currency note.\n", count);
18
            }
19
            if (remainder > 0 && this.nextDispenser != null) {
20
                this.nextDispenser.dispense(new PaperCurrency(remainder));
21
            }
22
        }
23
    }
24

          
25
}


Now we will define the ATM withdrawal process in order to define the use of paper currency dispenser. We will arrange the paper currency dispensers in higher to lower face value order.

Here's the code for ATMWithdrawal class:

Java
xxxxxxxxxx
1
25
 
1
package org.trishinfotech.responsibility;
2

          
3
public class ATMWithdrawal {
4

          
5
    protected static PaperCurrencyDispenser hundredDispenser = new HundredDispenser();
6
    protected static PaperCurrencyDispenser fiftyDispenser = new FiftyDispenser();
7
    protected static PaperCurrencyDispenser twentyDispenser = new TwentyDispenser();
8
    protected static PaperCurrencyDispenser tenDispenser = new TenDispenser();
9
    protected static PaperCurrencyDispenser dispenserChain;
10
    static {
11
        // construct the chain of the currency dispensers in higher to lower
12
        // denomination
13
        hundredDispenser.setNextDispenser(fiftyDispenser);
14
        fiftyDispenser.setNextDispenser(twentyDispenser);
15
        twentyDispenser.setNextDispenser(tenDispenser);
16
        dispenserChain = hundredDispenser;
17
    }
18

          
19
    public static void withdraw(PaperCurrency currency) {
20
        if (currency != null) {
21
            dispenserChain.dispense(currency);
22
        }
23
    }
24
}


Now its time to write our Main class to execute and test the output:

Java
 
xxxxxxxxxx
1
36
 
1
package org.trishinfotech.responsibility;
2

          
3
import java.util.Scanner;
4

          
5
public class Main {
6

          
7
    public static void main(String[] args) {
8
        try (Scanner scanner = new Scanner(System.in)) {
9
            do {
10
                System.out.println(
11
                        "Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): ");
12
                int amount = scanner.nextInt();
13
                if (isValid(amount)) {
14
                    ATMWithdrawal.withdraw(new PaperCurrency(amount));
15
                }
16

          
17
            } while (true);
18
        }
19
    }
20

          
21
    private static boolean isValid(int amount) {
22
        if (amount <= 0) {
23
            System.out.println("Invalid amount. Try again!");
24
            return false;
25
        } else if (amount > 1000) {
26
            System.out.println("Daily withdrawal limit is 1000$. Try again!");
27
            return false;
28
        } else if (amount % 10 != 0) {
29
            System.out.println("Amount must be mutiple of 10s, Try again!");
30
            return false;
31
        }
32
        return true;
33
    }
34

          
35
}


Below is the output of the program:

Plain Text
 
xxxxxxxxxx
1
37
 
1
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
2
150
3
Dispensing '1' 100$ currency note.
4
Dispensing '1' 50$ currency note.
5
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
6
20
7
Dispensing '1' 20$ currency note.
8
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
9
10
10
Dispensing '1' 10$ currency note.
11
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
12
110
13
Dispensing '1' 100$ currency note.
14
Dispensing '1' 10$ currency note.
15
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
16
250
17
Dispensing '2' 100$ currency note.
18
Dispensing '1' 50$ currency note.
19
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
20
220
21
Dispensing '2' 100$ currency note.
22
Dispensing '1' 20$ currency note.
23
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
24
201
25
Amount must be mutiple of 10s, Try again!
26
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
27
210
28
Dispensing '2' 100$ currency note.
29
Dispensing '1' 10$ currency note.
30
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 
31
580
32
Dispensing '5' 100$ currency note.
33
Dispensing '1' 50$ currency note.
34
Dispensing '1' 20$ currency note.
35
Dispensing '1' 10$ currency note.
36
Please enter amount to withdraw (multiple of 10, max 1000$, Press Ctrl + C to end): 


The Source Code can be found here: Chain-of-Responsibility-Design-Pattern-Sample-Code

The Chain of Responsibility, Command, Mediator and Observer offers various ways of connecting senders and receivers of requests.

  • The Chain of Responsibility pattern is used to sequentially pass a request along a dynamic chain of receivers until at least one of them handles it.
  • The Command pattern is used to establish unidirectional connection between sender and receiver objects.
  • The Mediator pattern is used to eliminate direct coupling between sender and receiver objects and force them to communicate indirectly via a mediator object.
  • The Observer pattern allows receivers to dynamically subscribe and unsubscribe for the requests.

I hope this tutorial helps in understanding of the chain of responsibility design pattern.

Liked the article? Please don't forget to press that like button. Happy coding!

This article also conclude my series of articles on basic design patterns. Please comment to tell me how much you like the articles? Based on your response, I will come with more articles on various technologies and languages like C++, Scala, Groovy, Big Data, Database along with Java.

Need more articles, please visit my profile: Brijesh Saxena

Design Java (programming language) Receiver (information theory) Requests Object (computer science) code style

Opinions expressed by DZone contributors are their own.

Related

  • Object Relational Behavioral Design Patterns in Java
  • Distribution Design Patterns in Java - Data Transfer Object (DTO) And Remote Facade Design Patterns
  • Context Object Design Pattern in Java: Introduction and Key Points
  • Java: Object Pool Design Pattern

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!