Lecture thumbnail 0:00 / 0:00 Okay.

So coming back to the classic implementation of Chain of Responsibility, I have to confess that I don’t

like it and there are many reasons why I don’t like it.

But the biggest reason is that the actual handle method here in our bonuses implementations actually

permanently modifies the creature.

It permanently modifies the creature.

It takes the creature and it modifies its state permanently.

I don’t want this.

I don’t think it’s a good idea.

I think that this prevents us from removing the modifiers later on.

So let’s suppose somebody removes or blocks or I don’t know, casts a spell to remove the double attack

modifier.

What happens to the creature?

And the answer is we have to recalculate the creature again by following the entire linked list.

Now I’m okay with this, but the way it’s implemented is a bit ugly because then you would have to somehow

revert the goblin to its original state.

And notice we’re not storing the original state.

We just have a single instance of goblin when we modify the goblin using modifiers.

So it becomes painful.

In addition, we have maybe too much exposure.

We have to expose the actual basic attack and defense values for them to be modified.

I don’t want to give outside components, right access to attack and defense because attack and defense

are typically defined at the beginning of the game.

They are predefined and then you can build bonuses on top of them.

So I don’t want this implementation.

I think it’s a classic Gang of four implementation, but it’s not great if you want the maximum flexibility.

So we’re going to rewrite everything completely and we’re going to use yet another design pattern.

In addition to chain of responsibility, we’re going to use the mediator design pattern.

So the mediator is like an in-between component that everyone uses to get some information.

And in our case, we’re going to call this mediator game because all of these goblins or other creatures,

they participate in a computer game and we want to have all of them refer to this game.

It’s very important for at least this particular implementation.

So here’s how it’s going to go.

The game is going to provide a query API for asking the attack or defense values of a particular creature.

And the way this is done in net at least is using events.

So I’m going to have a public event event handler query and query is going to be the query object.

So the query is where you specify what you want, who you actually want it from.

And then subsequently what happens is you also store the result of the query inside the query object

as well.

So we’re going to have public event handler query and we’re going to hold this queries.

There we go.

So I’m going to define a class called Query, and it’s going to be a class where you specify what exactly

you want.

So for example, we need to specify which creature we want information about so we can have public string

creature name, for example.

We can also specify what kind of argument we want to find out.

Do we want the attack value?

Do we want the defense value?

So for this I’ll make an enum, I’ll call it argument like so.

And we’re going to have either attack or defense.

So this is the argument.

And then of course, you need an instance of it.

So we have public argument what to query.

So we specify what kind of information we want from a creature.

And then of course, we want the query itself to store the value that’s being queried.

So we’ll have public int value.

Once again, I’m using public fields here.

It’s not an indication of how to program, but I’m just trying to save some time.

Okay.

So what we’re going to do now is we’re going to make a constructor.

Let’s make a constructor which initializes all of these because we need all of them for actual query.

Now, you’re probably wondering why do we need the initial value?

Why do we need to pass in the value?

And the reason is that if we have a bonus, we have a bonus on top of the initial value.

So this is the value that you pass in.

So if you have an attack value of two and a bonus of plus two, you pass in the two here and then the

event gets invoked and somebody gets to add another plus two on top of this.

So somebody takes the value here and adds an additional two and that’s what gets returned.

So very convenient approach.

Now, having made the query, we might also want to add an API inside game for actually firing those

queries.

So that’s fairly obvious.

So I’m going to make a method called perform query.

So we’re going to make a query and here you have to specify the sender and the query itself and you

simply take the event.

So you say queries, question mark, dot and you invoke passing the sender as well as the query.

So that’s all that we have to do here.

Okay.

So now we have a query API and the question is, well how can a creature support this API?

And this is rather easy as well.

So let’s make a creature and it’s similar to what we had before in a way.

So, but in addition, we also now take a reference to the game.

So we have private game game.

So this is.

Our mediator object.

In addition, we have.

I’m going to make a public string name.

So here I’m keeping the name public because I’m going to need it later on.

But it’s not critical.

You can make it private and make access as whatever and then I’ll have private int attack and defense

values.

Notice these are private.

You cannot really modify them because we assume that the creature is attacking.

Defense values are fundamental to that creature and they cannot be modified.

You can make bonuses and adjustments to those values, but you cannot.

You cannot define or change the fundamental values.

So now let’s make a constructor.

We need a constructor for pretty much everything here.

So short circuit some of these.

Whoops, what did I just do?

Let’s try this again.

So join in file.

There we go.

Okay, so having made this, we now want to actually let people access the creatures attack and defense

values.

So the way this is done, obviously we don’t want people to write to those values, but we do want people

to read those values.

So we make a property, we say public int attack and we make a getter.

Now the getter needs to collect all the bonuses.

So the question is how do you collect all the bonuses?

But luckily we have a mediator called game and this mediator can be used.

So we make a query.

We say, Oh, I’m going to query, I’m going to query the creature name, which is name in this case.

And that should be just ordinary name.

Actually, I should just use an ordinary constructor here.

Okay, so query, let’s take a look at the documentation here.

Hopefully.

Let’s take a look at this.

Okay, so creature name comes first.

We have to specify the name of the creature we’re trying to get information about.

We’re querying its attack value and the default value, the baseline value is attack.

So that’s our query.

And then what we do is we invoke it on the game.

So we say game dot, perform query and we specify the sender as this, even though in our scenario we’re

not using this particular argument, but it doesn’t really matter and we specify the query.

So at the end of this query we have Q dot value which contains the actual attack value, and that’s

what we return.

We return Q dot value.

There we go.

Now we can perform a similar operation on defense.

So I’m just going to duplicate this and we’ll have defense and you simply specify defense here.

So that’s the accessors for the attack and the defense.

Let’s also implement some sort of two string.

So I’m going to go into formatting members.

Now what I want to output is the name as well as the properties for attack and defense, not the fields,

the properties.

There we go.

So let’s press finish here and we are done with the creature and now we can implement those modifiers

once again.

And it’s going to be interesting how those come in.

So this time round I am actually going to make a base abstract class.

Now, in the previous example, we didn’t make an abstract class because we actually used the base class

as a root object as the definition of a linked list.

And this time around we don’t have a linked list at all.

So we are going to have an abstract class and it’s going to be called creature modifier just like before,

and it’s going to also implement Idisposable.

And the reason I’m doing this is so that you can add a modifier onto the creature temporarily and then

you can remove it later on.

So I’m illustrating the fact that you can in fact implement the removal of particular modifiers.

So now what does a modifier have?

Well, it has a reference to the game and it has a reference to the creature that’s being affected.

And both of these should be protected, by the way, because we are in an abstract class, so they cannot

just be private.

Let’s make them protected here.

Now we’re going to make a constructor as before, hopefully.

Let’s try this again.

There we go.

Here’s a constructor.

I’m going to once again implement all of these.

And then of course, we’re also going to have a method.

You can actually override in order to handle this particular scenario.

So just like in the previous example of handle, we’re going to have a handle, but it’s not intrusive.

It doesn’t affect the creature itself.

It only affects the query that’s being passed in.

So I’m going to make a protected abstract void handle which takes the sender as well as the query.

And that’s going to be used as the event handler for the events that we’ve made up above in the game.

Now, in addition, what I’m going to do is I’m going to actually subscribe to those events in the constructor

and unsubscribe in the dispose.

So in the constructor here, I’m going to say game dot queries plus equals handle.

So I am subscribing, but I’m subscribing something which is abstract.

So the derived classes are expected to actually fill in this gap and similarly in the dispose.

I say game dot queries minus equals handle.

There we go.

So we’ve got our base class and now we can inherit from this base class and we can add those wonderful

bonuses.

So if I want a double attack modifier, all I have to do is I have to inherit from creature modifier.

Let’s implement the missing members here.

And then, of course, in the handle, what I do is I don’t change the creature itself.

Instead, I check that this is the right creature, this is the creature that we want to modify.

So I say if the query is creature name.

Is equal to the creature name that I’m applying this to.

Because remember, double attack modifier applies to a particular creature which is taken as a constructor

argument and which is stored in a protected field here.

And that’s what we’re checking.

So we check that the name matches and we also need to check that we’re getting the right thing.

So.

Q Dot, what to query is equal to attack because attack is what we’re modifying.

So if we want to modify attack, what we do is we take Q dot value and hopefully it’s public.

Let’s take a look at yeah, it’s public here.

So we take the query value and we multiply it by two.

So.

Q Dot value multiply equals two.

There we go.

Okay, so this is the implementation of the double attack modifier.

And similarly, what we can do is we can implement an increase defense modifier, which is a creature

modifier, and once again we perform the typical operation.

So this time around we check that the creature name is equal to the appropriate name and we check that

what’s being queried?

Q Dot, what to query is in actual fact the defense value.

So if somebody wants the defense value, we take Q dot value and we increase it by two, for example.

So now we are done.

Let’s take a look at how all of this can be used.

So we’re going to make a game, new game like so, and we’re also going to make a goblin.

So that’s going to be a new creature, which is referring to the game.

Notice the game has to be passed in as a constructor argument and typically in the real world you would

use constructor injection from your container.

Then you specify the name of the creature.

Let’s have a strong goblin and let’s have the values three and three.

So this is a stronger goblin.

We’re going to writeline the goblin just to see what we’re getting, and then we’re going to modify

the goblin.

And because I implemented I disposable, we can do a using here so I can have a double attack modifier

passing the game and the goblin.

And here what I can do is I can writeline the goblin once again and I can writeline the goblin after

we’ve exited from this block.

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

So before we enter the block, the goblin is three three.

We enter the block and it becomes A63 because we double the value and then it is A33 again.

And we can combine this with the other attack modifier or rather the defense modifier.

So here I can make a new increased defense modifier once again passing in the game as well as the Goblin.

And in here I can once again writeline the Goblin.

And this time around notice what happens.

First of all, we double the attack, so it goes from 3 to 6 and then we increase the defense from 3

to 5.

And then both of these expire because they’re disposable.

So the dispose method calls and we’re back to three three.

So this is how you can implement chain of responsibility using what’s normally called an event broker,

because this thing brokers events being sent from one component to another and it’s a kind of a mediator.

So we saw two design patterns here, the chain of responsibility as well as the mediator.

Play Play Play Stop Start Play