The chain of responsibility behavioral pattern allows you to setup a series of possible results that you can initiate from a single location without worrying about what code will provide the result. Usually this pattern describes a single outcome but there can be more.
Many times, this pattern works with the composite design pattern in order to know which object to call next. The composite pattern provides a nice hierarchy of objects but you don’t have to use that pattern or that structure. As long as you have some means to provide one or more possible result handlers that each know about the next handler in line, then you have the means to follow this pattern.
Your code just calls the first handler and it can choose to do something or move to the next. These are just method calls and a handler is some object that decides it’s the best object to deal with the method call. If not, then the object passes control to the next object by calling the same method on the next object. The order that the handlers are called is very important and you normally want to make sure that the possible handlers are ordered so they’re looking at very specific criteria first, then a little broader criteria, then a little more, and so on, until you may want some handler that acts as a catch-all.
This pattern doesn’t guarantee that your request will be handled or which object will handle the request. That flexibility allows you to reduce coupling between your objects. If you know exactly which object you want to call to process a method call, then this pattern is not for you.
The decorator design pattern also calls from one object to the next. There is a big difference between these two patterns though. The decorator is trying to add new features or behavior to a base object. The chain of responsibility is just trying to figure out who will handle the request. Listen to the episode for more or read the full transcript below.
The basic description says that this pattern avoids coupling the sender of a request with its receiver by chaining multiple receivers and giving each one a chance to handle the request.
Let’s say you have a group of about 20 people that you want to organize into teams. A common way to do this is to select team captains who take turns selecting their team members. That’s actually opposite of how this pattern works. Here’s a better example that still uses team captains.
You first select a few team captains and give each captain some criteria for selecting their team members. Maybe the first captain is told to select anybody wearing sandals. Another captain should select anybody with the color blue. Another should select anybody with short hair. And another should select anybody. What happens?
In particular, which team will Bob join. Bob has short hair and is wearing blue sandals. The order here is very important. Because Bob meets the criteria for all the team captains, he’ll end up on the first team.
Another thing to consider is what happens if the captain with the criteria to select anybody goes first? Everybody will end up on that team.
Once you get your captains ordered properly usually from a very specific criteria to a broader criteria to an all-encompassing criteria, you’ll end up with good teams. Some criteria might be similar in scope such as the short hair vs. the color blue. The important point about all this is that the team structure is based on the criteria and the order of that criteria and that you can change this at any time.
Maybe halfway through the selection process, you notice a team getting large enough and decide to remove that captain from the lineup. Or you could always add a new captain. The choice is yours.
What’s this have to do with the chain or responsibility? I’ll explain that right after this message from our sponsor.
( Message from Sponsor )
In the adventure game that I’ve used for examples some attacks will likely be ranged attacks. That means the hero will throw something or shoot something or cast a spell that flies through the air. Now, the player might have an intended target in mind but things don’t always work out that way. How would you handle this in code. One way would be to gather anything that might be hit by the attack and order them from closest to farthest. then go down the line to see if there are any collisions. The first object that’s in the direct path usually stops the attack and takes the damage. This might even be a wall or a tree.
You might think, why can’t the game itself figure this out. Why would it need to ask several objects when the game engine already knows which object is first in the line of attack? Well, maybe because each object might be able to avoid the attack somehow. Instead of trying to make the game engine aware of all the criteria for one attack vs. another affecting each object in the path, it could just let each object handle the attack.
Let’s say the hero shot an arrow through a glass window. The window would definitely break but would do very little to stop the arrow. The next object in line would then have to deal with the arrow.
One aspect of this pattern that I haven’t described yet is that each object in line knows about the next object. You don’t need anything to coordinate the requests. The first object can handle the request or not and then decide to pass it to the next in line or not. And by request, I mean a method call that could initiate some action, provide some information, request information, etc.
Normally, the potential request handlers will know who’s next in line. This is often due to the composition pattern where complicated structures can be built. Each time a new object is added to the composite, it knows who its parent object is and can use that parent as the basis for the next in line with this pattern. Episode 66 describes the composite pattern.
You don’t have to base the next in line on a parent object though. And even if you use the composite pattern, you’re free to use a different arrangement for the ordering of the chain of responsibility handlers.
In the example I gave just now, the game engine figured out all the possible objects that could be affected by a ranged attack and put them in line and then sent the arrow to the first object. From then on, the object themselves could handle the next in line.
Episode 67 describes the decorator pattern which has some similarities to this pattern. The decorator also calls from one object to another until it gets to the real object. This chain of responsibility pattern calls from one object to another. the difference is that the chain of responsibility is not trying to add new behavior onto a real object. The chain of responsibility is just trying to figure out who will handle the method call. Once some object handles the request, the process is usually finished. Unlike the decorator where the call continues all the way to the end. I should also mention that this pattern doesn’t actually guarantee that a handler will be found. Your request might just be ignored or return some basic response.