Lecture thumbnail 0:00 / 0:00 All right.

So we’re going to look at the classic implementation of the chain of responsibility design pattern.

And we’re going to consider a scenario where we have a computer game where you have creatures fighting

out, perhaps a collectible card game or something like that.

You have a bunch of creatures and then you have modifiers on those creatures.

So a creature has an attack and defense values, and you can improve those values by adding additional

boosts, additional improvements, modifiers to that creature.

So let’s define the creature, first of all.

So I’m going to define a creature.

It’s going to have a name.

I’m going to be using public fields here, as I often do.

Please don’t take it as advice.

It’s just a way of quickly demonstrating certain things without having to mess about with properties

everywhere.

So we’re going to have attack and defense as well as the creature name, and we’re going to have a constructor

which initializes all of those things.

So fairly obvious stuff so far.

Now we’re also going to generate a two string implementation.

So let’s go and generate formatting members for the name of the creature, the attack and defense values.

And then we’re going to have this idea of a creature modifier.

So essentially we’re going to modify the attack and defense values of a creature by adding additional

modifiers.

And those modifiers are not going to be part of the creature itself.

They’re going to be external classes.

So once again, we’re not interfering in the structure of creature.

We’re making other classes for modifying the creature.

So we’re going to have something called a creature modifier.

So this is a class which actually facilitates the chain of responsibility design pattern.

So what we’re going to have is we’re going to have a reference to the creature.

So we’re going to have creature, creature.

And by the way, this should be protected, not private, because we intend to inherit from this class.

And in addition, we’ll have a protected creature modifier called next.

So this modifier next should give you a hint about what’s going on.

Effectively, what we’re doing with these chains of modifiers is we’re building a linked list.

So we’re essentially defining the modifier and then we have a reference to the next modifier and the

next modifier and so on and so forth.

Of course, this can be null, which means there is no next modifier in the chain of responsibility.

But there might be, so who knows?

Okay, so we’re going to make a constructor and we’re just going to initialize the creature here.

So I will initialize the creature in the constructor once again using a few C-sharp seven features along

the way.

And then we’re going to have a couple of methods.

So the first method that we’re going to have is a method called Add.

And this is where you add a new modifier to a creature.

So I know it might seem cryptic like, why would we call Add when we can just call the constructor?

Why shouldn’t the constructor perform this action?

But you’ll see in a moment what’s going on.

Because this creature modifier is quite simply, a base class.

It’s kind of like a collection of all the modifiers.

So you can think of the creature modifier itself as being a linked list.

So we’re just doing a linked list in a different way.

So when you add a new creature modifier, what you’re doing is you’re adding it to the end of this list.

So we have this linked list.

And if next is not equal to null, then we call next dot add with a creature modifier.

So we add it to the very end of the list.

But if next is in fact null, then we say next is equal.

CM So we set the next modifier.

Okay, now this is a base class, so I’m going to have a public virtual void handle and handle is the

method that’s going to be invoked when we actually want to apply the modifier to a creature.

So in this case, what we do is we call the next dot handle.

So essentially we have a modifier in a chain of modifiers and we tell each of the modifiers to apply

it, assuming it’s not null, of course.

So we say, next question mark, dot So we do it in a null safe way and we call handle here.

So that’s it.

That’s all that we have to do.

And now we can inherit from creature modifier to make our own modifier.

So for example, let’s suppose that we want to have a modifier which doubles the attack value of a creature.

So remember, a creature has an attack value and we want to double it.

We want to have maybe some sort of bonus for attack.

So in this case, what we’ll do is we’ll make a new class, let’s call it double attack modifier, and

it’s going to inherit from creature modifier.

Now, of course, we need to generate the constructor because the constructor has to call the base class

constructor.

There’s no avoiding it, unfortunately.

And then of course, what we do is we override the handle method here, so we make an override for it

and here we do the following.

So first of all, I’ll just put out some piece of information about what we’re doing.

So we’re doubling.

We’re doubling the creature creatures attack.

So we get creature dot name.

And notice we’re getting creature here.

That’s why it had to be protected back in the base class.

So we’re getting the creatures attack and we’re doubling it.

So doubling.

The creatures attack.

And then of course, we take creature dot attack and we multiply it by two.

And then what we do is we also call the base class handle.

And the reason why we’re calling the base class handle is because the base class implementation is the

one that actually walks the linked list.

So if there is a modifier after this particular modifier, we want to call that as well.

And we don’t want to reuse this code in here.

We don’t want to write next question mark dot handle here.

Instead, we just call base dot handle and that’s pretty much it.

So this is how you implement a double attack modifier and we can already start using this chunk of code.

So essentially if I go here and I make a goblin, so I’m going to make a goblin, which is a new creature.

So it’s a creature, its name is Goblin.

Its attack value is going to be two and its defense value is going to be two.

Then I can first of all write line the goblin just so we see what we’re actually getting here.

So let me execute this and we’ll take a look at what the the output of a creature is.

So we have a goblin with attack two and Defense two.

That’s good enough.

Now what we do is we make a creature modifier.

And essentially because this base class, this creature modifier is in fact our linked list, we can

treat it as a root object for any kind of modifiers that we want to add on top of the creature.

So the way this is done is you make a creature modifier and this is explains why we didn’t make it abstract.

So you might be wondering, well, if you just have this virtual thing, why not make it abstract and

just just repeat this code everywhere?

Well, no, that’s that’s not how we’re going to do it.

So essentially, we make a creature modifier.

So we make, let’s say var root equals new creature modifier, and we need to pass the creature in here.

So we’ll pass in the goblin in here and then let’s add a couple of bonuses.

So what we can do is we can add this double attack modifier.

So I’m going to write line.

So let’s double the goblins attack and I’m going to take the goblin and double its attack by saying

root, dot, add.

So we’re adding another modifier to this chain of responsibility and we’re saying, Well, we’re going

to have a modifier, which is a double attack modifier, which also takes the goblin, and that’s pretty

much it.

And now we can right line the goblin again.

And let’s take a look at what we actually get.

So after we double the attack, we still, for some reason have the attack value left as two.

And the reason is we didn’t apply the root.

So remember, it doesn’t work automatically.

You have to call this handle method in order to actually apply the root.

So we’re going to call root dot handle.

And this takes care of every single modifier in the chain.

So it works the entire chain.

Because if you look at root dot handle, what it does is it checks for next and then performs the handle.

So we can actually go ahead and debug this so that we get to see how we walk the chain.

So let’s actually do F5 here and look at how we walk the entire process.

Okay.

So we are going hopefully to land at a breakpoint.

So here we are at a breakpoint for root handle.

I’m going to step in and then here we are.

So we are now in creature modifier, not in its derived class, but in the creature modifier.

We’ll look at next and notice that next is not null.

So next is a double attack modifier.

So we step into that and then of course, we double the creatures attack.

So creature dot attack is multiplied by two and then we call base dot handle.

So if we step into this, we are now back into the base class and we once again call next question mark

handle.

But next this time round is null because we’ve come to the end of the chain of responsibility.

So we are effectively done.

Okay, So I’m going to stop this and I’m just going to run it without debugging.

So we get to see the nice output in the console.

Here we go.

So it’s now finally working.

We start with the goblin with attack value of two, but then we double the goblins attack value using

the modifier and now the goblin has an attack value of four.

Okay, so let’s see how we can mix it up.

Let’s see how we can have yet another modifier and put it on top.

So we’re going to have an increased defense modifier, increased defense modifier, which is also going

to be a creature modifier like so quickly implement the constructor and I’ll make the override for handle

like so.

And here of course, we write line increasing the creatures which is creature dot name by the way,

increasing the creatures defense like so.

And then I’m going to take creature dot creature with a small sea creature dot defense and increase

it by the value of three.

And then once again we call base dot handle.

There we go.

Okay, so having made this, I can now add it, add it to the route effectively.

So here we can say write line.

Let’s increase goblins defense.

So increase the defense value.

And the way this is done is you call root dot, add new increase defense modifier once again passing

in the goblin.

Unfortunately, we do have to pass it in.

And then once again we call root dot handle just once, which walks the entire linked list.

And then if we kind of execute this, you can see that the goblin starts with two two.

It doubles the attack from 2 to 4 and it increases the defense from 2 to 5.

So that’s exactly what we’re getting here.

So this is a very simple way of implementing the chain of responsibility.

The only last thing I wanted to show you is how you can actually stop the chain of responsibility in

its tracks by preventing further invocations, by preventing people from actually adding further elements

to this list.

So let’s suppose that somebody casts a spell on the goblin somewhere before all of these modifiers are

applied.

Some of the cast, some sort of protection spell on the goblin so the goblin cannot be buffed, the

goblin cannot have its values improved.

How would we implement this?

How would we implement this kind of no bonuses modifier?

And the way this is done is very simple.

We make a class called No Bonuses modifier and we inherit from creature modifier and we make the constructor.

We implement the override.

And we do absolutely nothing here now because we do absolutely nothing here, because there is no base

call.

This means that nobody is traversing the linked list from this point onwards.

And what I can do now is I can apply this modifier like right here, I can say route dot, add new no

bonuses modifier, and that’s pretty much it.

Now, if I execute this, you will see that the goblin starts out as two two.

We apply the no bonuses modifier and then even though we try to apply some additional modifiers here

and here, the result is still a goblin with the stats.

Two two because we’ve explicitly prevented the walk of the linked list, thereby preventing somebody

traversing this chain of responsibility and adding additional features to this particular goblin.

Play Play Stop Play Start Play information alert