Chain of Responsibility Pattern

Design Patterns Overview

Definition

Pass a Product to a Chain of Processors and Each Will Do Its Job.

Recipe

  • Define your ‘Product’ how ever you want.
1
class Product {/*implementation*/}
  • A chain is created out of links which satisfy at least 2 basic behaviors.
    • They can process a given ‘Product’ object.
    • They know about the next link in the chain.
1
2
3
4
interface ILink {
void process(Product product);
void setNextLink(ILink link);
}
  • Now let’s define a few links for our chain; each of which might or might not process the passed product.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class LinkA implements ILink {
ILink nextLink;
public void setNextLink(ILink link) { nextLink = link; }
public void process(Product product) {
/* perform process 'A' on the product. or not! */
if (nextLink != null) nextLink.process(product);
}
}
class LinkB implements ILink {
ILink nextLink;
public void setNextLink(ILink link) { nextLink = link; }
public void process(Product product) {
/* perform process 'B' on the product. or not! */
if (nextLink != null) nextLink.process(product);
}
}
class LinkC implements ILink {
ILink nextLink;
public void setNextLink(ILink link) { nextLink = link; }
public void process(Product product) {
/* perform process 'C' on the product. or not! */
if (nextLink != null) nextLink.process(product);
}
}

Serve

Now that the product and the chain links exist, the client needs only to weave the links together to make a chain and pass a product to its first link.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Client {
Client() {
ILink linkA = new LinkA();
ILink linkB = new LinkB();
ILink linkC = new LinkC();
/* creating a chain by introducing
* the next link of each link.
*/
linkA.setNextLink(linkB);
linkB.setNextLink(linkC);
linkA.process(new Product());
}
}

Important Benefits

This pattern decouples commands/handlers (e.g ‘Link’) and allows them to have their own independent logic.

Example

Suppose that you’re developing a module for the local post office to send out notifications to recipients when they receive a package. This notification message shall be sent by mail, sms and email. Accordingly our Message object could be designed as follows.

1
2
3
4
5
6
class Message {
String notificationContent;
String recipientPhone;
String recipientMail;
String recipientAddress;
}

The chain’s ‘Link’ interface is called ‘INotification’ and each implementation contains logic to send a message in a specific way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
interface INotification {
void setNext(INotification n);
void send(Message message);
}
class Sms implements INotification {
INotification next;
public void setNext(INotification n) { next = n; }
public void send(Message message) {
/* send a SMS message to the given number */
if (next != null) next.send(message);
}
}
class Email implements INotification {
INotification next;
public void setNext(INotification n) { next = n; }
public void send(Message message) {
/* send an email to the given mail address */
if (next != null) next.send(message);
}
}
class Post implements INotification {
INotification next;
public void setNext(INotification n) { next = n; }
public void send(Message message) {
/* print & mail to the given postal address */
if (next != null) next.send(message);
}
}

The client instantiates and links the notifiers to create a chain and finally passes the message to the first link of the chain.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Client {
Client() {
INotification sms = new Sms();
INotification mail = new Email();
INotification post = new Post();
sms.setNext(mail);
mail.setNext(post);
Message message = new Message();
/* set message properties to math recipient */
sms.send(message);
}
}

Design Patterns Overview

Share Comments