The chain of responsibility pattern describes an approach in which a message tickles down from one class to another. A class can either act on the message or allow it to be passed on to the next member of the chain. Depending on the implementation there are a few different rules that can be applied to the message passing. In some situations only the first matching link in the chain is permitted to act. In others, every matching link acts on the message. Sometimes the links are permitted to stop processing or even to mutate the message as it continues down the chain:
We’ll start with an interface to describe those who might listen to complaints:
export interface ComplaintListener{
IsAbleToResolveComplaint(complaint : Complaint):boolean;
ListenToComplaint(complaint: Complaint): String;
}
The interface requires two methods. The first is a simple check to see if the class is
able to resolve a given complaint. The second listens to and resolves the complaint.
Next we’ll need to describe what constitutes a complaint
var Complaint = (function () {
function Complaint() {
this.ComplianingParty = "";
this.ComplaintAbout = "";
this.Complaint = "";
}
return Complaint;
})();
Next we need a couple of different classes which implement ComplaintListener
and are able to solve complaints:
class ClerkOfTheCourt {
IsInterestedInComplaint(complaint){
if (isInterested())
return true;
return false;
}
ListenToComplaint(complaint){
//perform some operation
return "";
}
}
JudicialSystem.ClerkOfTheCourt = ClerkOfTheCourt;
class King {
IsInterestedInComplaint(complaint){
return true;
}
ListenToComplaint(complaint){
//perform some operation
return "";
}
}
JudicialSystem.King = King;
Each one of these classes implements a different approach to solving the complaint.
We need to chain them together making sure that the king is in the default position.
class ComplaintResolver {
constructor() {
this.complaintListeners = new Array();
this.complaintListeners.push(new ClerkOfTheCourt());
this.complaintListeners.push(new King());
}
ResolveComplaint(complaint) {
for (var i =0; i<this.complaintListeners.length; i++){
if
(this.complaintListeners[i].IsInterestedInComplaint(complaint))
{
return this.complaintListeners[i].ListenToComplaint(complaint);
}
}
}
}
There are variations of this pattern in which multiple listeners could fire, even allowing the listeners to mutate the parameters for the next listener.