Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:04,840 --> 00:00:09,190
So let's discuss a few of the sources of spaghetti code.
2
00:00:09,700 --> 00:00:15,310
But before we do that, let's ask ourselves why is it called spaghetti code in the first place?
3
00:00:15,640 --> 00:00:17,130
It might not be obvious to all of you.
4
00:00:17,140 --> 00:00:22,960
So if you've heard this term before, what it's getting at is the idea that when you've got a bowl of
5
00:00:22,960 --> 00:00:28,300
spaghetti like this and you pull it one strand, you're not sure which bits of the bowl are going to
6
00:00:28,300 --> 00:00:28,650
move.
7
00:00:28,810 --> 00:00:30,810
Where is the end of that spaghetti?
8
00:00:30,820 --> 00:00:31,480
Where is it?
9
00:00:31,480 --> 00:00:32,259
It's in a tangle.
10
00:00:32,259 --> 00:00:34,360
You can't quite see spaghetti code.
11
00:00:34,360 --> 00:00:34,810
Just like this.
12
00:00:34,810 --> 00:00:39,710
You change one bit of code and you are not sure what the repercussions are going to be.
13
00:00:39,730 --> 00:00:45,760
It could be wide reaching and chain have a bug in a piece of completely unrelated code.
14
00:00:45,760 --> 00:00:47,560
Or at least you thought it was unrelated.
15
00:00:47,980 --> 00:00:53,860
So that's my spaghetti code is bad because you go and make a change in one place and it has repercussions
16
00:00:53,890 --> 00:00:55,180
all over the place.
17
00:00:55,540 --> 00:01:01,390
What we want is you make a change in one class and it's mostly self-contained to that class with a little
18
00:01:01,570 --> 00:01:03,340
bit of changes elsewhere.
19
00:01:03,700 --> 00:01:11,530
Now, the static and global state are some commonly identified issues with code.
20
00:01:11,830 --> 00:01:16,210
Any use of static and global state is a bad thing.
21
00:01:16,240 --> 00:01:18,970
So what do you mean by static or global state?
22
00:01:19,000 --> 00:01:25,720
Well, it's these cases where you have a static public variable, even not necessarily public, but
23
00:01:25,720 --> 00:01:29,980
a static variable that's shared across the whole of your program.
24
00:01:30,880 --> 00:01:34,690
And you can edit it if it's constant that doesn't use a bug that way.
25
00:01:34,930 --> 00:01:40,180
But if it's something that can be modified by your program, then there is an issue.
26
00:01:40,180 --> 00:01:47,020
Here is why bugs that's the first thing is quite easy for that variable to change when you're not expecting
27
00:01:47,020 --> 00:01:50,010
it to, because somewhere else in the code it gets updated.
28
00:01:50,020 --> 00:01:54,250
You forgot that because your mind can't be everywhere in a large code base.
29
00:01:54,700 --> 00:01:56,050
And so bugs happen.
30
00:01:56,890 --> 00:01:58,330
Poor unit test ability.
31
00:01:58,340 --> 00:02:03,010
So this is not always a problem in games because we don't always unit test games for whatever reason.
32
00:02:03,010 --> 00:02:07,330
That might be a bad thing, but we don't often unit test games.
33
00:02:07,330 --> 00:02:11,390
But if you've got global state, that makes it virtually impossible or very hard.
34
00:02:11,390 --> 00:02:11,950
It's a unit.
35
00:02:11,950 --> 00:02:20,140
Test things properly because you can't set things up in isolation in a little test case code comprehension
36
00:02:20,380 --> 00:02:28,360
because global state variables are often declared far away or used far away from where you're currently
37
00:02:28,360 --> 00:02:32,110
reading the code, and their impact can be far away.
38
00:02:32,820 --> 00:02:34,660
They can be really hard to understand.
39
00:02:35,260 --> 00:02:36,820
When is that variable going to change?
40
00:02:36,830 --> 00:02:39,700
What should that variable be at this point in time?
41
00:02:39,700 --> 00:02:45,520
So someone coming into your code fresh or you coming in a few months time, you won't be able to know
42
00:02:45,790 --> 00:02:49,840
what to expect from that variable multithreading.
43
00:02:50,020 --> 00:02:51,580
Not so much an issue again with you.
44
00:02:51,670 --> 00:02:53,950
Secret tend to write single threaded code.
45
00:02:54,310 --> 00:03:02,230
But if you do have multi-threaded stuff, then this whole level of bugs just gets so much worse because
46
00:03:02,230 --> 00:03:03,910
threads can stomp all over each other.
47
00:03:04,180 --> 00:03:10,120
There can be performance issues around having multiple threads trying to access the same information
48
00:03:10,120 --> 00:03:11,500
and communication between threads.
49
00:03:12,040 --> 00:03:14,420
Its global state is absolutely a no go.
50
00:03:14,440 --> 00:03:20,140
When you've got multithreading involved and the last final argument is and then you need to.
51
00:03:20,170 --> 00:03:24,700
So you thought with that global state that only ever be one audio manager, you thought they'd only
52
00:03:24,700 --> 00:03:26,440
ever be one character in the game?
53
00:03:26,450 --> 00:03:31,630
Oh, suddenly we've decided we're going to have a team of player characters in the game.
54
00:03:31,870 --> 00:03:36,520
And now you thought that it was alright to have just one global mana variable.
55
00:03:36,550 --> 00:03:41,260
Well, now we need to manage variables one further player, one on one for player two.
56
00:03:41,560 --> 00:03:45,400
Wouldn't it have been better if we hadn't use global variables in the first place?
57
00:03:45,970 --> 00:03:50,020
So these are some of the common reasons we don't use global state.
58
00:03:50,020 --> 00:03:54,070
It creates a spaghetti code where we don't know what is involved with what.
59
00:03:54,580 --> 00:04:01,120
Here's an example Suppose we had a mana variable like I was saying, and we decided it'd be a good idea
60
00:04:01,120 --> 00:04:04,630
if this was a public only static global variable.
61
00:04:05,410 --> 00:04:10,900
So in our character, we might decide that we're updating the Mana every frame to recharge.
62
00:04:10,910 --> 00:04:15,490
And when you use an ability that cost gets subtracted from the Mana, obviously we'd put in some code
63
00:04:15,490 --> 00:04:17,980
here to make sure the bond doesn't get below zero and stuff like that.
64
00:04:17,980 --> 00:04:20,440
But for simplicity sake, we're just leaving it like this.
65
00:04:20,950 --> 00:04:26,710
Now, suppose you have another class somewhere else a magic potion that will restore your mana now for
66
00:04:26,710 --> 00:04:29,200
simplicity, because it can just get access to the Mana.
67
00:04:29,200 --> 00:04:30,010
It just does.
68
00:04:30,010 --> 00:04:31,780
It goes and restores that mana.
69
00:04:31,930 --> 00:04:34,390
Everything is working fine at the moment.
70
00:04:34,930 --> 00:04:40,600
What if I went in and added some code that tried to cap the Mana?
71
00:04:40,720 --> 00:04:43,960
Well, I would go and write it here where the money's being updated, right?
72
00:04:44,650 --> 00:04:51,670
Yes, except I'd introduce a bug because I could overcharge the mana by using a mana potion because
73
00:04:51,670 --> 00:04:55,090
I'm accessing this global state and I didn't realize it.
74
00:04:55,090 --> 00:04:57,040
It was coming out of left field for me.
75
00:04:57,040 --> 00:04:58,750
I didn't know it was there.
76
00:04:58,930 --> 00:05:03,490
Another source of spaghetti ification is communication.
77
00:05:03,600 --> 00:05:11,660
Asian between classes and this is where those two points of high cohesion and loose coupling come into
78
00:05:11,660 --> 00:05:12,500
the equation.
79
00:05:13,190 --> 00:05:16,040
So what is loose coupling and high cohesion?
80
00:05:16,040 --> 00:05:21,560
While I think this diagram kind of sums it up the best, imagine that these boxes are classes and inside
81
00:05:21,560 --> 00:05:28,780
them, the dots are variables and functions, and the lines between them are when a function axis is
82
00:05:28,790 --> 00:05:30,980
a variable or another function and so on.
83
00:05:31,730 --> 00:05:34,760
So what's going on here is the good example.
84
00:05:34,760 --> 00:05:37,850
At the top is one which has high cohesion and loose coupling.
85
00:05:37,850 --> 00:05:38,540
What do we mean by that?
86
00:05:38,540 --> 00:05:44,450
High cohesion means that the elements within the classes, the functions and variables refer a lot to
87
00:05:44,450 --> 00:05:45,040
one another.
88
00:05:45,050 --> 00:05:48,770
The functions use multiple variables, they use each other and so on.
89
00:05:49,490 --> 00:05:53,450
Loose coupling means the opposite is true between classes.
90
00:05:53,450 --> 00:05:58,130
One class will not try to access lots and lots of variables of another class.
91
00:05:58,980 --> 00:06:05,660
That's what happens when you have the bad example down here at the bottom, which is one that has low
92
00:06:05,660 --> 00:06:11,240
cohesion, meaning that the elements within the class don't really refer to each other very much.
93
00:06:11,600 --> 00:06:19,190
And tight coupling, which is when they actually refer a lot more to elements from other classes.
94
00:06:19,190 --> 00:06:25,160
You can see these two classes have a lot of functions and variables that reference each other across
95
00:06:25,160 --> 00:06:29,210
the class boundary, which means that these two classes are very tightly coupled.
96
00:06:29,570 --> 00:06:35,600
And this is usually a sign that your structure of classes isn't very good, and you should consider
97
00:06:35,600 --> 00:06:41,420
rejigging the classes and their responsibilities so that they can be higher.
98
00:06:42,140 --> 00:06:45,110
Have higher cohesion and more loose coupling.
99
00:06:45,140 --> 00:06:47,710
So here comes an example of this and a challenge for you.
100
00:06:47,720 --> 00:06:50,320
Why are these two classes here?
101
00:06:50,330 --> 00:06:50,960
Bad?
102
00:06:51,020 --> 00:06:55,490
Because the video and have a go and see if you could also rewrite it to be better.
103
00:06:59,740 --> 00:07:05,620
OK, so this if you haven't figured it out, it was low cohesion and tight coupling was what was wrong
104
00:07:05,620 --> 00:07:06,340
with these classes.
105
00:07:06,640 --> 00:07:12,400
So here's our low cohesion character class, which you can see what's location about it?
106
00:07:12,420 --> 00:07:15,820
Well, this knock back method only uses one variable the animator.
107
00:07:16,150 --> 00:07:23,470
The Shout method only uses the audio source and and the shout and take damage only uses the health.
108
00:07:23,480 --> 00:07:27,660
So you can see that essentially, we've almost got three separate classes here.
109
00:07:27,670 --> 00:07:33,640
We've got one that deals with the animation portion, which is this knockback method one class that
110
00:07:33,640 --> 00:07:37,780
deals with the audio portion and one class that deals with the health portion.
111
00:07:37,780 --> 00:07:39,120
So it's not very cohesive.
112
00:07:39,130 --> 00:07:44,590
We could split it up and there wouldn't be much communication between those classes, and we'd end up
113
00:07:44,590 --> 00:07:46,300
with more pie cohesion.
114
00:07:46,810 --> 00:07:53,410
Now, how about the tightly coupled enemy was the other problem, because this enemy knew an awful lot
115
00:07:53,410 --> 00:07:58,330
of information about the character, for instance, ET knew all of these methods.
116
00:07:58,330 --> 00:08:03,850
It used three of its methods here when it only has three, so that's pretty tightly coupled.
117
00:08:04,330 --> 00:08:09,760
And then we also knew how to access and how to find this character.
118
00:08:09,760 --> 00:08:12,040
So in start, it's actually finding the character.
119
00:08:12,310 --> 00:08:14,350
That's another thing that needs to know about that class.
120
00:08:14,680 --> 00:08:21,100
And if we change where the character is located, if we changed any of these methods that are all reasons
121
00:08:21,430 --> 00:08:24,970
why we would have to come and also change the enemy.
122
00:08:25,360 --> 00:08:31,840
So spaghetti code is when you make one change in one file and you have to change 15 other files.
123
00:08:32,169 --> 00:08:36,039
Good code, you should make a change in one file, maybe two.
124
00:08:36,309 --> 00:08:37,570
But that should be it.
125
00:08:37,659 --> 00:08:43,990
If it's good code, it's resilient to changing and doesn't need a scattershot surgery across the whole
126
00:08:44,169 --> 00:08:44,840
code base.
127
00:08:46,030 --> 00:08:50,170
So how could we improve this and a high cohesion character?
128
00:08:50,530 --> 00:08:57,670
We might say, Well, let's take more responsibility for taking a hit, and that's going to be all rolled
129
00:08:57,670 --> 00:09:03,950
up into one method which accesses the animator, the audio and the health components of this character.
130
00:09:03,970 --> 00:09:10,120
This is now a high cohesion class because the function axis is multiple of those variables and it's
131
00:09:10,120 --> 00:09:12,040
much more tightly integrated.
132
00:09:13,150 --> 00:09:18,760
The loosely coupled enemy, on the other hand, might just and this is why they go hand in hand, high
133
00:09:18,760 --> 00:09:19,810
cohesion and loose coupling.
134
00:09:19,810 --> 00:09:25,330
Because now that we have a high cohesion character, the coupling to the enemy has improved because
135
00:09:25,330 --> 00:09:27,040
we now just call take hit.
136
00:09:27,400 --> 00:09:30,430
Well, I've also improved here is we've used an interface.
137
00:09:30,430 --> 00:09:36,640
If you're not seen interfaces before, they're just a way of saying, I want this, it's a contract.
138
00:09:36,640 --> 00:09:41,050
Basically, I want this method to be implemented on whatever object is passed in.
139
00:09:42,040 --> 00:09:47,050
So now what we've got is that instead of relying directly on the high cohesion character class, we
140
00:09:47,050 --> 00:09:48,280
could even swap that out.
141
00:09:48,280 --> 00:09:52,960
Instead of having a character, we could have an NPC object as long as it implemented.
142
00:09:52,960 --> 00:09:55,760
I attachable, we would be able to call Typekit on it.
143
00:09:55,780 --> 00:10:02,650
So now we don't even have the we're not even coupled to the way of finding that class in enemy.
144
00:10:02,680 --> 00:10:07,360
We just get past that target and that's how we do the damage to it.
145
00:10:07,420 --> 00:10:16,360
Now, obviously, this is quite a toy example, but you can see from this example how cohesion and coupling
146
00:10:16,360 --> 00:10:18,400
it goes hand in hand.
147
00:10:18,490 --> 00:10:25,570
Now, in the next lecture, we are going to look at composition and inheritance and why you should prefer
148
00:10:25,570 --> 00:10:27,370
the former over the latter.
149
00:10:27,400 --> 00:10:27,970
I'll see you then.
15540
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.