The pattern revolves around a chain of processing objects, where each checks whether it can handle a request. If it cannot, it passes the request to the next processor in the sequence.
Key Components
- Base Processor: An abstract definition that includes a reference to the next link in the chain and a method for handling requests.
- Concrete Processor: Specific implementations that evaluate the request. If the criteria are met, they process it; otherwise, they dleegate to the next link.
- Client: Sets up the chain structure and initiates the first request. The client remains decoupled from the specific handling logic.
Example Scenario: Leave Approval
Consider a system where leave requests are processed based on duration:
- Team Lead: Approves up to 1 day.
- Project Manager: Approves up to 3 days.
- Director: Approves up to 7 days.
Adding a new approval level simply requires adding a new processor to the chain without altering existing logic, adhering to the Open/Closed Prniciple.
Base Processor Definition
public abstract class ApprovalNode {
protected ApprovalNode nextNode;
public void setSuccessor(ApprovalNode nextNode) {
this.nextNode = nextNode;
}
public abstract void processLeave(int requestedDays);
}
Concrete Processors
Team Lead Handler:
public class TeamLead extends ApprovalNode {
@Override
public void processLeave(int requestedDays) {
if (requestedDays <= 1) {
System.out.println("Request approved by Team Lead.");
} else if (nextNode != null) {
nextNode.processLeave(requestedDays);
} else {
System.out.println("No handler available for this duration.");
}
}
}
Project Manager Handler:
public class ProjectManager extends ApprovalNode {
@Override
public void processLeave(int requestedDays) {
if (requestedDays > 1 && requestedDays <= 3) {
System.out.println("Request approved by Project Manager.");
} else if (nextNode != null) {
nextNode.processLeave(requestedDays);
} else {
System.out.println("No handler available for this duration.");
}
}
}
Director Handler:
public class Director extends ApprovalNode {
@Override
public void processLeave(int requestedDays) {
if (requestedDays > 3 && requestedDays <= 7) {
System.out.println("Request approved by the Director.");
} else if (nextNode != null) {
nextNode.processLeave(requestedDays);
} else {
System.out.println("No handler available for this duration.");
}
}
}
Client Implementation
public class ClientDemo {
public static void main(String[] args) {
// Initialize chain components
ApprovalNode lead = new TeamLead();
ApprovalNode manager = new ProjectManager();
ApprovalNode director = new Director();
// Link the chain
lead.setSuccessor(manager);
manager.setSuccessor(director);
// Submit request
System.out.println("Submitting request for 5 days:");
lead.processLeave(5);
}
}