WEBVTT

1
00:00:01.140 --> 00:00:02.880
<v Instructor>So we already implemented</v>

2
00:00:02.880 --> 00:00:05.840
a part of the Forkify application.

3
00:00:05.840 --> 00:00:10.320
But at this point, it has no structure whatsoever.

4
00:00:10.320 --> 00:00:14.690
And so now it's time to talk about the project architecture,

5
00:00:14.690 --> 00:00:19.490
but also about software architecture more in general.

6
00:00:19.490 --> 00:00:21.600
Now, we touched on this already

7
00:00:21.600 --> 00:00:25.070
in the Mapty application a little bit earlier.

8
00:00:25.070 --> 00:00:28.793
But in this lecture, let's now go a little bit deeper.

9
00:00:30.310 --> 00:00:32.960
And first of all, why do we even need

10
00:00:32.960 --> 00:00:35.653
an architecture when we build software?

11
00:00:36.500 --> 00:00:39.900
Well, there are actually multiple reasons.

12
00:00:39.900 --> 00:00:43.200
First, the architecture will give our project

13
00:00:43.200 --> 00:00:47.350
the structure in which we can then write the code.

14
00:00:47.350 --> 00:00:52.350
So just like a house, software also needs a structure.

15
00:00:52.690 --> 00:00:55.900
Now in software, structure basically means

16
00:00:55.900 --> 00:00:58.750
how we organize and divide the code

17
00:00:58.750 --> 00:01:03.190
into different modules, classes, and functions.

18
00:01:03.190 --> 00:01:06.070
So all these will basically hold our code

19
00:01:06.070 --> 00:01:09.020
together and give it structure.

20
00:01:09.020 --> 00:01:11.543
The next reason is maintainability.

21
00:01:12.550 --> 00:01:14.800
So when we build a project,

22
00:01:14.800 --> 00:01:17.690
we always need to think about the future

23
00:01:17.690 --> 00:01:22.290
and keep in mind that the project is never really done.

24
00:01:22.290 --> 00:01:24.200
It is never finished.

25
00:01:24.200 --> 00:01:27.440
We will always need to change things in the future

26
00:01:27.440 --> 00:01:30.570
and we will need to maintain the project.

27
00:01:30.570 --> 00:01:35.400
And that only works if the project is nicely structured.

28
00:01:35.400 --> 00:01:40.180
Plus, we might even want to add new features to the project,

29
00:01:40.180 --> 00:01:42.073
which brings us to expandability.

30
00:01:43.370 --> 00:01:46.470
So expandability is basically

31
00:01:46.470 --> 00:01:51.300
the ability to easily add new features in the future.

32
00:01:51.300 --> 00:01:55.730
And once again, that is only possible with a good structure,

33
00:01:55.730 --> 00:01:58.550
and a good overall architecture.

34
00:01:58.550 --> 00:02:01.891
So the perfect architecture is basically one

35
00:02:01.891 --> 00:02:05.440
that allows for all these three aspects

36
00:02:05.440 --> 00:02:10.440
of structure maintainability, and expandability.

37
00:02:10.590 --> 00:02:14.280
Now, in order to achieve that perfect architecture,

38
00:02:14.280 --> 00:02:19.130
we can of course create our own architecture from scratch.

39
00:02:19.130 --> 00:02:23.310
And that's exactly what we did in the Mapty project.

40
00:02:23.310 --> 00:02:25.110
However, that only works

41
00:02:25.110 --> 00:02:28.810
with a really small project like that one.

42
00:02:28.810 --> 00:02:31.620
But when the project grows more complex,

43
00:02:31.620 --> 00:02:33.510
then it's going to be very hard

44
00:02:33.510 --> 00:02:37.720
to achieve a good architecture completely on our own.

45
00:02:37.720 --> 00:02:41.930
And so instead, we can opt for a well established

46
00:02:41.930 --> 00:02:44.470
architecture pattern that developers

47
00:02:44.470 --> 00:02:48.640
have been using for years, or even for decades.

48
00:02:48.640 --> 00:02:52.480
And examples of that are model view controller,

49
00:02:52.480 --> 00:02:57.480
model view presenter, flux, and many other architectures.

50
00:02:58.000 --> 00:03:00.960
And so that is actually what we're going to do

51
00:03:00.960 --> 00:03:02.900
in the Forkify project,

52
00:03:02.900 --> 00:03:07.200
because it's a bit more complex than the Mapty project.

53
00:03:07.200 --> 00:03:10.390
Now these days, in modern web development,

54
00:03:10.390 --> 00:03:14.900
many developers actually use a framework like react,

55
00:03:14.900 --> 00:03:18.200
Angular, Vue or Svelte

56
00:03:18.200 --> 00:03:21.900
to take care of the architecture for them.

57
00:03:21.900 --> 00:03:24.710
And so in this case, developers don't have to think

58
00:03:24.710 --> 00:03:27.690
a lot about architectures on their own.

59
00:03:27.690 --> 00:03:29.580
And probably this is actually

60
00:03:29.580 --> 00:03:32.240
a good idea at a certain point,

61
00:03:32.240 --> 00:03:36.200
especially for large scale applications.

62
00:03:36.200 --> 00:03:40.970
However, and this is key, as I said many times before,

63
00:03:40.970 --> 00:03:44.400
it is very important that you really know JavaScript,

64
00:03:44.400 --> 00:03:47.920
before switching to some of these frameworks.

65
00:03:47.920 --> 00:03:50.700
And in my opinion, that includes knowing

66
00:03:50.700 --> 00:03:54.260
how to implement an architecture by yourself.

67
00:03:54.260 --> 00:03:57.680
And so that's what I will teach you with this project,

68
00:03:57.680 --> 00:04:00.670
among many other things of course.

69
00:04:00.670 --> 00:04:04.200
And so this will make it so much easier for you

70
00:04:04.200 --> 00:04:08.300
to learn React, or Vue or whatever framework

71
00:04:08.300 --> 00:04:11.200
that you choose later down the road.

72
00:04:11.200 --> 00:04:14.410
Now no matter where the architecture comes from,

73
00:04:14.410 --> 00:04:16.150
and who develops it,

74
00:04:16.150 --> 00:04:20.920
there are some components that any architecture must have.

75
00:04:20.920 --> 00:04:23.280
And that is business logic,

76
00:04:23.280 --> 00:04:27.770
state, an HTTP library, application logic,

77
00:04:27.770 --> 00:04:30.140
and presentation logic.

78
00:04:30.140 --> 00:04:33.520
So business logic is basically all the code

79
00:04:33.520 --> 00:04:36.770
that solves the actual business problem.

80
00:04:36.770 --> 00:04:39.950
So that's code that is directly related

81
00:04:39.950 --> 00:04:43.860
to what the business does and to what it needs.

82
00:04:43.860 --> 00:04:46.870
So if your business is what's up,

83
00:04:46.870 --> 00:04:50.950
then your business logic will include sending messages.

84
00:04:50.950 --> 00:04:53.450
Now if your business is a bank,

85
00:04:53.450 --> 00:04:56.600
then one of the many parts of business logic

86
00:04:56.600 --> 00:04:59.370
will be to store transactions.

87
00:04:59.370 --> 00:05:02.810
But if you business is a budget manager,

88
00:05:02.810 --> 00:05:05.210
then your business logic will certainly

89
00:05:05.210 --> 00:05:07.750
include calculating taxes.

90
00:05:07.750 --> 00:05:09.682
So you get the point.

91
00:05:09.682 --> 00:05:14.230
So essentially, business logic is the logic

92
00:05:14.230 --> 00:05:17.340
that is really related to solve the problem

93
00:05:17.340 --> 00:05:21.272
that the business set out to solve in the first place.

94
00:05:21.272 --> 00:05:26.272
Next is the state which is one of the most important aspects

95
00:05:26.790 --> 00:05:29.290
of any web application.

96
00:05:29.290 --> 00:05:32.350
So the application state is essentially

97
00:05:32.350 --> 00:05:34.530
what stores all the data about

98
00:05:34.530 --> 00:05:37.750
the application that is running in the browser.

99
00:05:37.750 --> 00:05:41.783
So the data about the applications front end basically.

100
00:05:42.670 --> 00:05:45.600
So the state should store any data

101
00:05:45.600 --> 00:05:47.981
that you might fetch from an API

102
00:05:47.981 --> 00:05:49.693
or data that the user inputs,

103
00:05:49.693 --> 00:05:54.693
or what page the user is currently viewing and so on.

104
00:05:55.000 --> 00:05:56.650
And this data should be

105
00:05:56.650 --> 00:05:59.560
the so called single source of truth,

106
00:05:59.560 --> 00:06:03.900
which should be kept in sync with the user interface.

107
00:06:03.900 --> 00:06:07.820
So that means that if some data changes in the state,

108
00:06:07.820 --> 00:06:11.730
then the user interface should reflect that.

109
00:06:11.730 --> 00:06:14.240
And the same is true the other way around.

110
00:06:14.240 --> 00:06:16.774
So if something changes in the UI,

111
00:06:16.774 --> 00:06:19.820
then the state should also change.

112
00:06:19.820 --> 00:06:22.650
Now storing and displaying data

113
00:06:22.650 --> 00:06:24.880
and keeping everything in sync

114
00:06:24.880 --> 00:06:27.180
is one of the most difficult tasks

115
00:06:27.180 --> 00:06:29.520
when building web applications.

116
00:06:29.520 --> 00:06:31.364
And that's why there are actually

117
00:06:31.364 --> 00:06:36.364
many state management libraries like Redux or MobX.

118
00:06:36.820 --> 00:06:40.730
But in this project, we will keep things very simple

119
00:06:40.730 --> 00:06:45.440
and use a simple object to store our entire state.

120
00:06:45.440 --> 00:06:49.283
Next, the HTTP library is simply responsible

121
00:06:49.283 --> 00:06:53.440
for making and receiving AJAX requests.

122
00:06:53.440 --> 00:06:56.590
And we have been doing that using the fetch function

123
00:06:56.590 --> 00:06:59.730
and so that's what we will keep doing here.

124
00:06:59.730 --> 00:07:02.640
And most real world applications of course,

125
00:07:02.640 --> 00:07:04.800
need some interaction with the web.

126
00:07:04.800 --> 00:07:08.780
And so that's why this is an aspect to keep in mind.

127
00:07:08.780 --> 00:07:11.450
Now about the presentation logic,

128
00:07:11.450 --> 00:07:14.570
this is the code that is only concerned

129
00:07:14.570 --> 00:07:18.550
about the implementation of the application itself.

130
00:07:18.550 --> 00:07:22.480
So it's more the technical aspects of the application,

131
00:07:22.480 --> 00:07:24.670
which are not directly related

132
00:07:24.670 --> 00:07:27.420
to the underlying business problem.

133
00:07:27.420 --> 00:07:30.100
So for example, application logic

134
00:07:30.100 --> 00:07:35.100
includes handling of UI events and navigation on the page.

135
00:07:35.560 --> 00:07:37.800
That's the reason why this component

136
00:07:37.800 --> 00:07:40.750
is many times also called a router.

137
00:07:40.750 --> 00:07:45.270
So basically mapping actions to the users navigation.

138
00:07:45.270 --> 00:07:47.680
Finally, the presentation logic,

139
00:07:47.680 --> 00:07:50.093
which is also called the UI layer,

140
00:07:50.093 --> 00:07:54.563
is of course all about the visible part of the application.

141
00:07:55.630 --> 00:07:59.480
So essentially, we can say that the presentation logic

142
00:07:59.480 --> 00:08:01.890
is responsible for displaying

143
00:08:01.890 --> 00:08:05.012
the application state on the user interface,

144
00:08:05.012 --> 00:08:07.893
in order to keep everything in sync.

145
00:08:08.731 --> 00:08:12.250
Now any good architecture

146
00:08:12.250 --> 00:08:15.860
has a way of separating all these components.

147
00:08:15.860 --> 00:08:20.420
So instead of mixing everything together in one big file,

148
00:08:20.420 --> 00:08:22.860
and in one big mess.

149
00:08:22.860 --> 00:08:25.770
And so let's now take a look at a well established

150
00:08:25.770 --> 00:08:28.330
architecture pattern that we're going to use

151
00:08:28.330 --> 00:08:29.653
in this project.

152
00:08:30.520 --> 00:08:35.000
And that is the model view controller architecture.

153
00:08:35.000 --> 00:08:39.420
So basically, this architecture contains three big parts,

154
00:08:39.420 --> 00:08:43.390
which are the model, the view and the controller.

155
00:08:43.390 --> 00:08:47.300
Now the view is of course, for the presentation logic.

156
00:08:47.300 --> 00:08:50.590
So it's the part of the application interacting

157
00:08:50.590 --> 00:08:51.713
with the user.

158
00:08:52.570 --> 00:08:56.250
The model is all about the applications data.

159
00:08:56.250 --> 00:08:58.743
And so that's why it usually contains

160
00:08:58.743 --> 00:09:02.120
the state and also the business logic

161
00:09:02.120 --> 00:09:04.130
that manipulates the state.

162
00:09:04.130 --> 00:09:07.700
So these two should be kept closely together.

163
00:09:07.700 --> 00:09:12.150
Now, the model is also what contains the HTTP library,

164
00:09:12.150 --> 00:09:15.150
that might get some data from the web.

165
00:09:15.150 --> 00:09:18.450
So like from some API or some back end.

166
00:09:18.450 --> 00:09:22.350
And so this is of course also about the data,

167
00:09:22.350 --> 00:09:25.490
and so it also goes into the model.

168
00:09:25.490 --> 00:09:27.030
Finally, the controller

169
00:09:27.030 --> 00:09:30.020
is what contains the application logic.

170
00:09:30.020 --> 00:09:34.100
And it kind of sits between the model and the view.

171
00:09:34.100 --> 00:09:36.640
So it basically creates a bridge

172
00:09:36.640 --> 00:09:40.100
between the model and a view which in fact,

173
00:09:40.100 --> 00:09:42.860
should know nothing about each other.

174
00:09:42.860 --> 00:09:45.660
So again, the model and the view

175
00:09:45.660 --> 00:09:49.340
will exist completely independent from one another,

176
00:09:49.340 --> 00:09:54.140
and not even knowing that the other one exists, basically.

177
00:09:54.140 --> 00:09:56.590
And in fact, one of the big goals

178
00:09:56.590 --> 00:10:00.960
of the MVC pattern so of this model view controller

179
00:10:00.960 --> 00:10:03.400
architecture is to actually

180
00:10:03.400 --> 00:10:07.200
separate business logic from application logic,

181
00:10:07.200 --> 00:10:11.630
which makes developing the application so much easier.

182
00:10:11.630 --> 00:10:13.060
But as a consequence,

183
00:10:13.060 --> 00:10:16.920
we then need something to connect these two parts.

184
00:10:16.920 --> 00:10:18.883
And so that is the controller.

185
00:10:20.032 --> 00:10:23.680
Now let's actually take a look

186
00:10:23.680 --> 00:10:27.300
at a typical flow of actions and of data

187
00:10:27.300 --> 00:10:28.815
as soon as some event happens

188
00:10:28.815 --> 00:10:33.730
on the user interface for example like a click.

189
00:10:33.730 --> 00:10:37.230
So to start, it's going to be the controller

190
00:10:37.230 --> 00:10:39.350
who will handle that event,

191
00:10:39.350 --> 00:10:40.970
because handling an event

192
00:10:40.970 --> 00:10:43.660
is doing something in the application.

193
00:10:43.660 --> 00:10:48.150
And that is clearly part of the application logic.

194
00:10:48.150 --> 00:10:50.140
Now, this handling might involve

195
00:10:50.140 --> 00:10:54.010
updating the user interface and also ask the model

196
00:10:54.010 --> 00:10:55.940
for some data.

197
00:10:55.940 --> 00:10:59.980
So we can say that the controller dispatches tasks

198
00:10:59.980 --> 00:11:04.160
to model and to the view or in other words,

199
00:11:04.160 --> 00:11:08.580
it controls and orchestrates this entire action.

200
00:11:08.580 --> 00:11:12.220
And in fact, the whole application itself.

201
00:11:12.220 --> 00:11:15.310
Now asking the model for some data might,

202
00:11:15.310 --> 00:11:19.510
of course involve doing an AJAX request to the web.

203
00:11:19.510 --> 00:11:22.960
And so that's exactly what the model does.

204
00:11:22.960 --> 00:11:24.920
Then, when the data arrives,

205
00:11:24.920 --> 00:11:29.430
the controller takes the data and sends it to the view.

206
00:11:29.430 --> 00:11:32.220
And so finally to finish the view,

207
00:11:32.220 --> 00:11:35.600
will render that data to the user interface,

208
00:11:35.600 --> 00:11:37.573
and finish this whole cycle.

209
00:11:38.480 --> 00:11:42.593
Now in this diagram, you see two types of arrows.

210
00:11:42.593 --> 00:11:46.630
So the dotted arrows represent data flow

211
00:11:46.630 --> 00:11:48.570
between the different parts,

212
00:11:48.570 --> 00:11:50.920
while the solid arrows represent

213
00:11:50.920 --> 00:11:54.720
actual function calls and module imports.

214
00:11:54.720 --> 00:11:58.710
So analyzing this, we can see that it's only the controller

215
00:11:58.710 --> 00:12:02.470
who imports and calls functions from the model,

216
00:12:02.470 --> 00:12:06.300
and from the view, but never the other way around.

217
00:12:06.300 --> 00:12:10.210
And so as I mentioned before, the model and view

218
00:12:10.210 --> 00:12:15.210
are in fact completely standalone and completely isolated.

219
00:12:15.375 --> 00:12:19.710
So again, they don't import each other,

220
00:12:19.710 --> 00:12:22.340
and they don't even import the controller.

221
00:12:22.340 --> 00:12:24.750
And in fact, they don't even know

222
00:12:24.750 --> 00:12:26.980
that the controller exists.

223
00:12:26.980 --> 00:12:29.830
All they do is to basically just sit there

224
00:12:29.830 --> 00:12:33.696
waiting to get some instructions from the controller.

225
00:12:33.696 --> 00:12:37.680
And this part is pretty important to understand.

226
00:12:37.680 --> 00:12:40.693
So take some time to really analyze this.

227
00:12:41.530 --> 00:12:43.820
Now, there are actually different ways

228
00:12:43.820 --> 00:12:46.630
of implementing the MVC pattern,

229
00:12:46.630 --> 00:12:49.340
where some are more complex than others.

230
00:12:49.340 --> 00:12:52.350
But this one is my favorite way of doing it,

231
00:12:52.350 --> 00:12:55.600
because I think it makes the most sense.

232
00:12:55.600 --> 00:12:59.670
But anyway, let's know see this MVC architecture

233
00:12:59.670 --> 00:13:02.310
applied to the part of the Forkify

234
00:13:02.310 --> 00:13:05.223
application that we already implemented.

235
00:13:07.010 --> 00:13:09.820
And so this is a flowchart of loading

236
00:13:09.820 --> 00:13:13.920
and rendering a recipe that we already implemented.

237
00:13:13.920 --> 00:13:16.900
And then down there, there's also a reminder

238
00:13:16.900 --> 00:13:20.910
of the MVC diagram that we just analyzed.

239
00:13:20.910 --> 00:13:23.970
So in this flowchart, handling these events

240
00:13:23.970 --> 00:13:27.048
is associated to the controller.

241
00:13:27.048 --> 00:13:31.178
Then loading the recipe happens in the model.

242
00:13:31.178 --> 00:13:34.010
So the controller basically calls

243
00:13:34.010 --> 00:13:36.720
some function that is in the model.

244
00:13:36.720 --> 00:13:38.870
And then the model asynchronously

245
00:13:38.870 --> 00:13:41.803
gets the recipe data from the API.

246
00:13:42.710 --> 00:13:45.060
And once that data has arrived,

247
00:13:45.060 --> 00:13:48.706
the controller asks for that data, receives it,

248
00:13:48.706 --> 00:13:52.600
sends it to the view, which will then ultimately

249
00:13:52.600 --> 00:13:55.140
render the recipe on the screen.

250
00:13:55.140 --> 00:13:57.030
And that's it.

251
00:13:57.030 --> 00:13:59.980
So that's what every step of the flowchart

252
00:13:59.980 --> 00:14:04.104
is associated to in the MVC architecture.

253
00:14:04.104 --> 00:14:07.330
But this is still quite abstract.

254
00:14:07.330 --> 00:14:09.770
Because remember, the flowchart

255
00:14:09.770 --> 00:14:14.740
is simply what we will implement, not how we will do that.

256
00:14:14.740 --> 00:14:17.150
And so let's go even deeper,

257
00:14:17.150 --> 00:14:19.750
and actually take a look at a detailed

258
00:14:19.750 --> 00:14:24.150
implementation diagram of or MVC architecture.

259
00:14:24.150 --> 00:14:26.750
And again, this is only about loading

260
00:14:26.750 --> 00:14:29.070
and rendering a recipe.

261
00:14:29.070 --> 00:14:32.050
And let's start by noticing how both the model

262
00:14:32.050 --> 00:14:35.990
and controller are implemented in a module,

263
00:14:35.990 --> 00:14:40.030
while the recipe view is actually a class.

264
00:14:40.030 --> 00:14:42.257
And we will explore the reasons for this

265
00:14:42.257 --> 00:14:44.700
when we actually write the code.

266
00:14:44.700 --> 00:14:47.310
But now once again, let's analyze

267
00:14:47.310 --> 00:14:49.800
the same data and actions flow,

268
00:14:49.800 --> 00:14:53.600
but this time in this real implementation.

269
00:14:53.600 --> 00:14:56.747
So when the user clicks on a search result,

270
00:14:56.747 --> 00:15:00.850
there is a control recipes function in the controller

271
00:15:00.850 --> 00:15:04.570
and this is the one that will handle this event.

272
00:15:04.570 --> 00:15:08.490
And how exactly that happens doesn't matter for now.

273
00:15:08.490 --> 00:15:11.070
So we will come back to this later.

274
00:15:11.070 --> 00:15:13.340
What matters is that this controller

275
00:15:13.340 --> 00:15:16.490
will instruct the recipe view to render

276
00:15:16.490 --> 00:15:19.470
a loading spinner while the user interface

277
00:15:19.470 --> 00:15:22.090
waits for the data to arrive.

278
00:15:22.090 --> 00:15:24.200
In the meantime, the controller

279
00:15:24.200 --> 00:15:27.356
also called the load recipes function in the model

280
00:15:27.356 --> 00:15:32.356
to fetch the recipe data from the Forkify API.

281
00:15:32.480 --> 00:15:35.945
Now the model also contains a big state object

282
00:15:35.945 --> 00:15:38.760
that we export from the model.

283
00:15:38.760 --> 00:15:42.320
And this state will contain all sorts of data,

284
00:15:42.320 --> 00:15:47.320
like the current recipe, search results, bookmarks, etc.

285
00:15:47.440 --> 00:15:50.720
But anyway, as the data arrives,

286
00:15:50.720 --> 00:15:54.190
it will be stored in this state object.

287
00:15:54.190 --> 00:15:58.160
And the controller then reaches into the state object,

288
00:15:58.160 --> 00:16:00.190
grabs the recipe data,

289
00:16:00.190 --> 00:16:02.520
and finally calls the render method

290
00:16:02.520 --> 00:16:06.070
on the recipe view with that data.

291
00:16:06.070 --> 00:16:08.000
So in order to finally render

292
00:16:08.000 --> 00:16:11.220
the recipe to the user interface.

293
00:16:11.220 --> 00:16:15.140
So basically the exact same steps as before,

294
00:16:15.140 --> 00:16:18.810
but this time actually implemented in our code.

295
00:16:18.810 --> 00:16:22.530
well, at least in theory and so next up,

296
00:16:22.530 --> 00:16:24.660
let's actually go from theory

297
00:16:24.660 --> 00:16:28.810
to practice and implement this architecture in our code.

