- Overview
- Transcript
4.3 Chain of Responsibility
The easiest way to describe this pattern is by analogy to a tech support organization. Imagine that a request needs to get serviced, but only a certain type of support rep can handle it. So the request comes into the queue and is passed down the line of support reps until one of them can complete it. That, in a nutshell, is the chain of responsibility pattern.
1.Introduction2 lessons, 04:27
1.1Introduction01:39
1.2Prerequisites02:48
2.Creational Patterns5 lessons, 52:47
2.1Factory10:16
2.2Abstract Factory12:24
2.3Singleton09:09
2.4Prototype09:18
2.5Builder11:40
3.Structural Patterns7 lessons, 1:05:54
3.1Adapter10:07
3.2Flyweight10:33
3.3Proxy05:53
3.4Bridge10:35
3.5Decorator11:44
3.6Composite09:43
3.7Facade07:19
4.Behavioral Patterns9 lessons, 1:25:42
4.1Iterator09:32
4.2Command07:48
4.3Chain of Responsibility13:47
4.4Mediator08:16
4.5Memento08:53
4.6Interpreter14:31
4.7Observer08:58
4.8Strategy07:36
4.9State06:21
5.Conclusion1 lesson, 02:42
5.1Conclusion02:42
4.3 Chain of Responsibility
Now it's time to talk a little bit about the chain of responsibility pattern. Now the chain of responsibility pattern has probably the longest name of any of the patterns that we will be covering or have covered so far, but it's really not that daunting and once you understand the basic premise, the concept kind of flows fairly naturally. So let's start by creating a playground, and this is going to be the chain od responsibility pattern, or the core pattern, and what we wanna do now is make sure that we put this into the behavioral folder. Okay, so what we wanna do is start with the basic idea. And the basic idea here is that we can create a bunch of different actors in this particular pattern that are capable of all understanding some sort of request that is flowing through a pipeline if you wanna think of it that way. But only certain types of actors are able to take action on that particular request. So if a request comes through the pipeline and an actor can act on it, it will process that request. And then everything else after that will leave it alone or has the option of leaving it alone. And if that particular actor can't process that request, then it just continues down the pipeline. So let's go ahead and start to create something like that. And the basic idea here is we're going to create a simple support type organization application that will allow us to create support requests and have the series of support reps that may or may not be able to process that request. So the first thing we're going to do is we're going to create a enumeration that's going to be severity. So we will all be able to create different levels of severity and attach them to these requests. And let's just create a couple of these. We'll say we have a low, is going to be equal to 1, and we have a medium and a high. And then after that we have the concept of a request. So let's go ahead and create a class and this is going to be a SupportRequest. And within here we have a couple different pieces of information. We're going to have that severity that we just created. So that's what's going to dictate how important this is going to be. We can give all of these a name. So let's say this is going to be a name, and then we also are going to have a flag in here as to whether or not this particular action has been completed. This is gonna be a Boolean and by default it's gonna be false. So we are assuming that when we create this request initially, it's going to be false because we haven't actually completed it yet. Then let's create an initializer for both the severity and the names. We'll do name first and then the severity, which is going to up-type severity. And then we'll just initialize name = name, and then self.severty = severity. So now we have our basic SupportRequest class. Now we need some actors or some people that can act on these requests. So before we do that let's start by creating some protocols so we're speaking the same language across the board. So we're gonna start by creating a protocol called a support rep protocol, which is basically going to represent anybody that can handle support requests. And this is going to contain a function called processRequest, and that's going to take in a request of type SupportRequest. So probably nothing too overly complicated, or something that you don't quite understand that you can probably start to see where this is going. So then, what we wanna do, is we want to create a class called SupportRep, which is going to be a SupportRepProtocol. Okay, so now what we can do is we can start to create this class for the SupportRep. And we can start to dictate what this person is capable of doing. This person is going to have a particular level. That means that, this is maybe a junior level, or a senior level, or a mid level. Or maybe it's level one, level two, level three, or whatever sort of support structure you are familiar with and then a severity to which that support rep can handle. And then it's also going to have another concept in there which is going to enable this chain of responsibility kind of concept. And that's gonna be that it's going to know who or what the next level of the support organization is going to be. So we kinda have this chain of command. We start low at the junior level, and then we move up higher to the senior level. So lets start building this out, we're gonna start by creating a couple properties. So we're gonna need to specify the severity that this particular rep can handle. We're going to give this rep a level name so we could call it things like junior, or mid, or senior, things like that. And then it's also going to need to know about the next level rep. So who is the next one in line if this particular one can't process the request? And there may or may not be one. So we're going to specify that it can be optional, because we don't know that this is the last line of defense or not. So then, of course, we will go ahead and initialize here. We'll set the severity, is going to be a severity type. Then we'll also go in to set the level, which will be a string. And then we'll go ahead and set those properties. Okay, so that handles all of the initializations. But there's still some pieces of functionality we need to be able to handle. The first one is we wanna be able to set that next level support rep if we possibly can. So we'll just create another function here called set NextLevelRep, which is going to take in that NextLevelRep of types support rep. And then all we're going to do is set that NextLevelRep equal to the one that we're passing in. Okay, so that'll take care of that one if necessary, and then we need to be able to process that request if possible. So the way that we're gonna handle this is the first thing we need to do is check to see is this request already been processed, and if it has we're just going to let it go. So we'll say if request.completed then we're just going to return. We don't wanna do anything with it at that point, we just want to let it continue down the pipeline. Okay, but now we also need to check whether or not we can actually do anything with it. So we'll say if request, severity.rawvalue, so it's integer value. If its integer value is less than or equal to the severity that I can handle myself, or that this particular rep can handle, if it matches or is part of that or if I'm able to process this request then I wanna do something with it. So I'm just going to do a print line here and I will say request and then I'll print out its name. So the request.name has been processed by a, and then we'll put in the level, level support rep, just like that. Okay, so that way we know that we've hit a support rep that can actually process that request, but that's not enough. We need to go ahead and say request.completed = true. So that we know we're actually done processing this and anybody else that sees this request coming through will just leave it alone, because it's already been taken care of. Then, we can start to pass this request down the line again and we'll go ahead and check to see if there is a NextLevelRep. And if there is, we'll go ahead and pass this request on, and if not, it's just basically going to end there. So we'll say, if NextLevelRep is not equal to nil, then we'll just go ahead and say, NextLevelRep.processRequest, and we'll send this request along. Okay, so now we've basically built a very simple class that's going to model a support rep, and now what we wanna do is we wanna create a support organization, right? So we wanna have a whole collection of these support reps that are handling this so we can send a message into the group and know that somebody or someone along the way is going to go a head and handle that request. So let's create a class called the support group and it's going to have a number of support reps which is going to be an array of support rep objects. Then we go ahead and initialize that, so we can say, supportReps and that is going to be an array of SupportRep objects. self.supportReps is gonna be equal to SupportReps, all right? And then at this point we're basically ready to be able to process our request. So I can say func processRequest, and then we'll go ahead into our request is going to be a SupportRequest, like that. All right, and so now what we need to do is we need to say that we have received a request and we'll print some information out about it and then we'll go ahead and try to push this request down the pipeline and see what happens. So we'll say print, received and then we'll send here what the request severity is. request_severity level support request; and then we'll just type in here that it is processing. Just like that, okay? So now basically what we wanna do is we wanna grab whatever then first rep is that we can find in there and then just go ahead and start to pump it down the line. So we'll say if let firstRep = supportReps and we'll just go ahead and grab the first one. And if there is one then we'll just say first rep dot process request, and we'll send that request down the line. So we'll go ahead and do that and then at the very end we'll check to see if the request got completed, and if it did we'll simply print out a line here that says successfully processed request, like that. And then for some reason it didn't, which I'll give you an example of in a little bit, we'll say unable to find representative to process request. Okay, so now we have a support group, we have a number of different support representatives. Let's start to build these out. Let's say we have a junior, which is going to be a supportRep and that supportRep can handle low severity. And the name is going to be Junior. Then we're gonna have a mid, is going to be another supportRep. And you can obviously build these out as much as you would like, or assign different values to them if you would like. This is gonna be a Mid and then we'll have a senior, which is going to be a SupportRep who can handle high level. And this is going to be Senior for the level, okay? So now we have these, then we can go and start to tie them together, so we can say the Junior, we wanna set the NextLevelRep is going to be the mid. And then we can take the mid and say that the NextLevelRep here is going to be the senior. Now we can create a group and say a group is equal to a SupportGroup. And then within here we're simply going to pass them along in here so we have a junior, we have a mid and then we have a senior. And now we can create a request. And that request is going to be a SupportRequest. And then we'll just give it a name. We'll say we need to maybe upgrade laptop or something like that. And this is probably a low but we always tend to go a little high when it comes to these support requests. So we'll specify it as a medium. And then we can come down in here and say group, I wanna process the request, and I'm gonna send in my request. Now if we've done everything correctly, what we should see down at the bottom is some text. All right, so we've received a medium level SupportRequest, which is processing. The request upgrade laptop has been processed by a mid level support rep And now we've successfully processed that request. So now as you can see we've created this chain of responsibility where we've started from the junior level all the way on up to the senior level, and they're all kind of linked together. So we can enter in a request or something in the very beginning, and it's gonna follow right down the chain, until someone or something can process that request successfully. Well, hopefully something can process that request successfully and then eventually it will make it out the end. And everybody is all excited that something was able to process that request. Now if for some reason we added in another severity up here let's say it was super Or something like that. If I came in here and put this in as super, then we're gonna run into a problem, because we don't have any reps that can handle something at that support level. So it's gonna go all the way through the chain of responsibility and have nothing able to process it. So we're gonna see that we received that request, but we were unable to find a representative to process it. So as you can see here we may or not be able to finally process a request. But in the end, we have now used the chain of responsibility pattern to at least create the chain to be able to process requests like this.







