Chain Of Responsibility
Story
The Chain of Responsibility allows an object to send a command without knowing which object will receive and handle it. The request is sent from one object to another making them parts of a chain and each object in this chain can handle the command, pass it on or do both.
Service request to call center is example of the Chain of Responsibility. Request can be handled at front desk level, supervisor level or any higher level. Correct handler of request is only known during execution of the request when request is traversing at various levels.
UML
Implementation
Handler.java
package com.hundredwordsgof.chainofresponsibility;
/**
*
* Handler interface, declares an interface for request handling
*
*/
abstract class Handler {
protected Handler succesor;
abstract void handleRequest();
public void setSuccesor(Handler succesor) {
this.succesor = succesor;
}
}
ConcreteHandler1.java
package com.hundredwordsgof.chainofresponsibility;
/**
*
* ConcreteHandler1 class, handles the request, can access to the next object in
* a chain and forward the request if necessary.
*
*/
public class ConcreteHandler1 extends Handler {
private boolean handleRequestInvoked = false;
void handleRequest() {
handleRequestInvoked = true;
// if some condition call handleRequest on successor
if (handleRequestInvoked) {
succesor.handleRequest();
}
}
protected boolean isHandleRequestInvoked() {
return handleRequestInvoked;
}
}
ConcreteHandler2.java
package com.hundredwordsgof.chainofresponsibility;
/**
*
* ConcreteHandler2 class, handles the request, can access to the next object in
* a chain and forward the request if necessary.
*
*/
public class ConcreteHandler2 extends Handler {
private boolean handleRequestInvoked = false;
void handleRequest() {
handleRequestInvoked = true;
}
protected boolean isHandleRequestInvoked() {
return handleRequestInvoked;
}
}
Usage
ChainOfResponsabilityTest.java
package com.hundredwordsgof.chainofresponsibility;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* Test implementation of the ChainOfResponsability pattern.
*/
public class ChainOfResponsabilityTest {
@Test
public void testChainOfResponsability() throws Exception {
// create two handlers
Handler concreteHandler1 = new ConcreteHandler1();
Handler concreteHandler2 = new ConcreteHandler2();
// connect handler in chain
concreteHandler1.setSuccesor(concreteHandler2);
// handleRequest on handlers is not invoked
assertEquals(false,
((ConcreteHandler1) concreteHandler1).isHandleRequestInvoked());
assertEquals(false,
((ConcreteHandler2) concreteHandler2).isHandleRequestInvoked());
concreteHandler1.handleRequest();
// handleRequest on handlers is invoked
assertEquals(true,
((ConcreteHandler1) concreteHandler1).isHandleRequestInvoked());
assertEquals(true,
((ConcreteHandler2) concreteHandler2).isHandleRequestInvoked());
}
}