00:00:00
hey my name is Forest welcome back in
00:00:01
today's video you're going to learn
00:00:02
about seven different software design
00:00:04
patterns many of which you already use
00:00:06
whether you realize it or not because
00:00:08
simply put there solutions to Common
00:00:09
programming problems that appear over
00:00:11
and over and over and
00:00:13
over regardless of what language or
00:00:15
platform you're using it's not
00:00:17
complicated it's just a matter of
00:00:18
knowing them so you can understand when
00:00:21
to use them and to actually use them
00:00:23
because they are common practice for a
00:00:26
reason because they're good back in 1994
00:00:29
these four developers known as the gang
00:00:31
of four wrote this book they documented
00:00:34
cataloged and formalized 23 commonly
00:00:37
used design patterns so i' highly
00:00:38
recommend reading that book reading all
00:00:40
the way through it because all of those
00:00:41
are heavily applicable today we're not
00:00:43
going to go over all 23 but I must note
00:00:45
that all 23 do fall into three buckets
00:00:49
creational patterns are all about object
00:00:51
creation so instead of creating objects
00:00:53
directly these patterns give you more
00:00:55
flexibility on how objects come into
00:00:57
existence structural patterns it's a
00:00:59
second in category deal with how objects
00:01:02
relate to each other think of them as
00:01:04
blueprints for building something
00:01:08
building larger structures from
00:01:09
Individual pieces like Legos so
00:01:12
creational patterns object creation
00:01:14
structural patterns the structure of how
00:01:16
they relate to each other in the third
00:01:17
category behavioral patterns which
00:01:20
handle communication between objects how
00:01:23
they interact and distribute
00:01:25
responsibilities which includes the
00:01:27
greatest pattern of all time the
00:01:28
strategy pattern just just always use a
00:01:30
strategy pattern if you take anything
00:01:32
nothing from this video take that but
00:01:33
let's dive deeper into these three
00:01:35
creational patterns starting with the
00:01:37
Singleton pattern everyone hates it
00:01:39
until they need it think of the
00:01:41
Singleton pattern as your apps logging
00:01:44
system when errors happen across your
00:01:46
app which we all know will happen since
00:01:49
you're the one coding it you want one
00:01:50
Central logger handling everything using
00:01:53
consistent formatting and and writing to
00:01:56
the same file or service you don't want
00:01:58
you don't want different loggers in
00:01:59
interfering with each other for example
00:02:02
this is where you have multiple loggers
00:02:04
and creating chaos logger one new logger
00:02:07
logger two new logger which is another
00:02:09
logger writing to the same file the
00:02:11
single T pattern you have a single
00:02:13
logger that everyone uses and you get
00:02:16
the instance from said logger logger one
00:02:19
logger two one logger get instance of
00:02:22
that logger stored in logger you'll want
00:02:24
to use the Singleton pattern when you
00:02:26
absolutely need a single instance that's
00:02:29
accessible globally like a database
00:02:32
connection pool or the logger but it
00:02:35
does have some trade-offs the good is
00:02:37
that you get guaranteed single instance
00:02:39
and Global access the bad is that well
00:02:43
it's a bit of a nightmare to test and
00:02:44
that's because you can't easily mock it
00:02:47
you can mock it but you can't easily
00:02:48
mock it and if you want to call that a
00:02:50
skill issue by all means try it yourself
00:02:53
then get back to me and tell me how it
00:02:55
went but also in multi-threaded
00:02:57
environments you need special handling
00:03:00
to prevent creating multiple instances
00:03:02
but if you want me to really scare you
00:03:03
I'm going to I'm going to use this
00:03:05
analogy a Singleton is basically just a
00:03:10
global a glorified Global
00:03:13
variable yeah think about that for a
00:03:15
second makes me nervous just thinking
00:03:16
about it but I'm not trying to scare you
00:03:18
it's not all bad or anything like that
00:03:21
it's like a using a hammer to solve your
00:03:23
problems sure it works great on nails
00:03:25
but not everything is a nail that's
00:03:27
that's the thing just use it when you
00:03:30
genuinely need single instance guarantee
00:03:33
not when you just want a global state
00:03:35
next up is the Builder pattern never
00:03:37
tried to create something that has like
00:03:39
15 different optional
00:03:42
parameters just me no all right anyway
00:03:45
you can think of the Builder pattern as
00:03:47
uh well think about creating a complex
00:03:50
API request you've got headers query
00:03:52
prams body data data data timeout
00:03:56
settings rry logic trying to do all of
00:03:58
that in a single Construction will look
00:04:00
something like this as you can see new
00:04:02
HTTP requests and we're just throwing in
00:04:04
API example.com post and all of this
00:04:08
based on our HTTP request class like
00:04:13
this however the beauty of the Builder
00:04:15
pattern is that you can chain methods in
00:04:17
any order you can skip the optional ones
00:04:19
and your code actually reads like
00:04:20
English check this out so here's our
00:04:23
class request Builder which starts off
00:04:25
similar to our HTTP request URL string
00:04:28
method string headers record string
00:04:30
string however here we're assigning it
00:04:32
an initial value in the below we have
00:04:35
all of our methods as you can see and
00:04:37
our Constructor results in a beautiful
00:04:40
Builder P pattern as such and what's
00:04:43
great about this is that if you want to
00:04:45
add any new options later you just have
00:04:47
to add a method to the class no need to
00:04:49
go through and update every single place
00:04:51
you're creating an object you want to
00:04:53
use a builder pattern every time you're
00:04:55
staring at a Constructor that has more
00:04:56
parameters than you have fingers or when
00:04:58
you need to construct object step by
00:05:00
step like cooking you don't just throw
00:05:02
all the ingredients in at once you
00:05:03
follow a recipe step by step the
00:05:06
downside is you end up writing more code
00:05:09
up front that is but trust me your
00:05:12
future self and all of your teammates
00:05:13
will than you when they can actually
00:05:15
understand what in the world's going on
00:05:17
and can create objects without you know
00:05:19
playing the game oh I wonder what this
00:05:20
parameter does next is the factory
00:05:23
pattern you know how an object-oriented
00:05:24
programming like my beloved Java we're
00:05:26
always creating objects with new this
00:05:28
and new that
00:05:30
as you've seen here well the factory
00:05:31
pattern says hold up let me handle that
00:05:34
for you think about creating different
00:05:36
types of users in your app you got
00:05:38
admins you got regular users you got
00:05:40
moderators here's what that could look
00:05:42
like without a factory yeah not the
00:05:45
cleanest thing under the sun if type
00:05:47
admin user create new admin or type
00:05:50
moderator user new moderator or else
00:05:52
user new regular user but if we were to
00:05:55
follow the factory pattern boom that's
00:05:58
it that's it we use user Factory we
00:06:02
create an admin id1 Nam John as you can
00:06:07
see up here and then the type is thrown
00:06:09
into a switch statement so all of that
00:06:12
messy Logic the object creation logic is
00:06:17
hidden in the factory class and all we
00:06:20
have to do to create a new user is this
00:06:23
it's just like when you're driving down
00:06:25
the road and you look at a factory oh
00:06:26
that's a that's a car plant you know
00:06:29
that cars pop out of there but you don't
00:06:32
see all of the intricacies and
00:06:34
complexity and this and that of what's
00:06:37
going on inside the factory because you
00:06:39
don't need to know any of that or at
00:06:41
least you don't need to focus on that
00:06:43
every single time you see a car come out
00:06:45
of there so just like with the code you
00:06:47
have you have the macro idea of what's
00:06:49
being popped out instead of worrying
00:06:52
about all of the logic every single time
00:06:54
you need to create a new user and then
00:06:56
for us if we want to change how an ad is
00:06:59
created just update the factory need to
00:07:02
add logging every time a moderator is
00:07:04
created update the factory want to start
00:07:06
pulling and reusing user objects update
00:07:10
the factory you want to use factories
00:07:12
every single time you see yourself using
00:07:15
that new keyword all over your code base
00:07:18
the downside of a factory is that you're
00:07:20
adding another layer of
00:07:23
abstraction but is that really a bad
00:07:25
thing I don't think so the real downside
00:07:27
in my opinion is that there annoyingly
00:07:30
coupled H they are very dependent on the
00:07:34
factory class but the flexibility you
00:07:36
get in return overall it it's worth the
00:07:39
trade-off for sure and your code becomes
00:07:41
way more maintainable because all of the
00:07:43
creation logic is in the same place in
00:07:46
that factory class it manages the
00:07:49
complexity just like twin gate manages
00:07:51
the complexity of dealing with vpms for
00:07:54
accessing development environments and
00:07:56
internal tools and just to be clear twin
00:07:58
gate the sponsor of this portion of
00:07:59
today's video is not a a VPN it's a
00:08:03
modern replacement if you will here's
00:08:06
the difference instead of exposing your
00:08:08
services to the public internet or
00:08:10
dealing with slow VPN connections twin
00:08:12
gate creates secure direct connections
00:08:15
to exactly what you need when you're
00:08:17
working remotely as a developer that
00:08:19
could be your staging environment
00:08:20
internal tools Cloud resources whatever
00:08:23
you get instant access with Incredible
00:08:26
performance while everything stays
00:08:28
completely PR you can manage everything
00:08:30
as code with their terraform provider it
00:08:32
has a kubernetes operator for service
00:08:34
deployment and the setup is remarkably
00:08:37
simple in short twin gate allows
00:08:38
developers to securely access work
00:08:40
resources remotely via zero trust
00:08:42
network access with the Speed and
00:08:44
Performance you need for development
00:08:45
work this means that you can easily
00:08:47
control exactly who has access to what
00:08:50
which is perfect for development teams
00:08:52
want to learn more and try it out well
00:08:53
click the link in the description and
00:08:55
see how twin gate can transform your
00:08:57
development workflow okay now on to the
00:09:00
second category that was a creational
00:09:02
category this is the structural
00:09:05
structural patterns starting with facade
00:09:07
the facade pattern is exactly what it
00:09:09
sounds like putting up a a pretty front
00:09:12
to hide everything behind it and you may
00:09:14
be saying well isn't this kind of
00:09:15
similar to what we just discussed the
00:09:18
factory hides all of the stuff inside
00:09:20
the factory remember creational patterns
00:09:24
are for object creation structural
00:09:26
patterns are how objects relate to each
00:09:29
each other and the facade pattern it is
00:09:31
kind of odd how it's like it's a pattern
00:09:35
I mean it makes sense it's fully
00:09:37
detailed they uh it is a design pattern
00:09:41
with specific implementation patterns
00:09:44
and use cases but really it it's really
00:09:48
just good programming technique I guess
00:09:49
all of these are good programming
00:09:50
technique but this one is really hard to
00:09:52
miss anyway uh let me move on to my
00:09:55
analogies you guys know how much I love
00:09:56
my analogies so if you're watching this
00:09:58
video you like how I EXP explain things
00:09:59
trying to put them into layman's terms
00:10:01
because that always helps me out make
00:10:03
sure you subscribe because that's how I
00:10:04
explain everything if you don't like it
00:10:06
you're not going to like the rest of my
00:10:07
videos but you know how when you order
00:10:08
something online and you put in your
00:10:11
card d da and you click buy now and then
00:10:13
well I mean magically everything else
00:10:16
happens well behind that simple
00:10:18
button a payment is being processed
00:10:21
there are inventory checks there are
00:10:23
shipping calculations fraud detection
00:10:25
but you as the customer
00:10:30
you don't really care I mean you care
00:10:31
about fraud detection things of that
00:10:32
nature but you don't really care about
00:10:33
everything that's going on behind the
00:10:35
facade right behind the buy now button
00:10:38
that's that's the idea here it's it's
00:10:41
kind of just a really fancy word for
00:10:44
encapsulation yeah I kind of like that
00:10:46
it's a fancy word for encapsulation
00:10:47
let's look at some code so without the
00:10:49
facade oh Lord help us this is what it's
00:10:51
like so new payment processor stored
00:10:54
over here new inventory system stored
00:10:56
over here so on and so forth everything
00:10:58
that we just disced us and then we run
00:11:00
through if fraud Checker if inventory
00:11:03
system if payment processor bless your
00:11:05
heart if you got to maintain all this
00:11:06
and that is without a facade and you'd
00:11:09
have to write this every single time
00:11:12
however with the facade you create a new
00:11:15
order facade and you may be wondering
00:11:17
well what happened to all of these
00:11:19
aspects in the facade well all of that
00:11:21
code is within our order facade class
00:11:25
payment processor payment processor as
00:11:27
you can see here then we have our
00:11:29
instructor and then we have place order
00:11:32
which has all of our if statements here
00:11:34
to check through everything and this is
00:11:36
all the code you need to write because
00:11:38
we're using a facade where again if you
00:11:40
weren't you'd have to write this every
00:11:43
single time use a facade pattern when
00:11:45
you just have a mess of complex
00:11:48
subsystems that you need to simplify so
00:11:50
for programming it's exactly like that
00:11:52
we get the outward appearance of the
00:11:54
interface or class that we're
00:11:56
interacting with and it hides all of
00:11:59
that information all the complexity
00:12:01
within it so we don't have to worry
00:12:02
about it every single time the only real
00:12:04
downside of a facade or at least the
00:12:08
downside that I would like to point out
00:12:09
is when it could become a god object I'm
00:12:13
what's called a Celestial
00:12:16
sweetheart a Celestial like a
00:12:20
god small G son knowing too much and
00:12:24
doing too much but compared to spreading
00:12:26
the complexity everywhere I'll take the
00:12:28
trade-off and you're probably using
00:12:30
facades all the time without realizing
00:12:31
it think of a HTTP client you just call
00:12:35
fetch API users and you get your data
00:12:37
right you don't care about TCP
00:12:39
connections or retry logic or header
00:12:41
parsing or any of that low-level stuff
00:12:43
and I mean this is actually built into
00:12:45
programming languages like an array list
00:12:47
in Java it's hiding all sorts of array
00:12:50
resizing complexity behind a clean
00:12:52
interface array list that's the beauty
00:12:54
of facades they're everywhere in good
00:12:57
code next is the adapter pattern which
00:12:59
is a very easy one simple one to
00:13:01
understand because we deal with adapters
00:13:03
in real life all the time have you ever
00:13:05
had a laptop that you wanted to connect
00:13:07
to a TV that it didn't have like any
00:13:11
like what the 2016 MacBook Pro it didn't
00:13:13
have the proper ports so you used an
00:13:15
adapter to go from a USB port to a HDMI
00:13:20
port the naming of these design patterns
00:13:22
is not supposed to be complex it is very
00:13:24
simple very um intentional very specific
00:13:28
it it's an adapter and you want to use
00:13:30
the adapter pattern when you're
00:13:32
integrating third-party libraries or
00:13:34
apis that don't quite match what your
00:13:37
code expects so let's say the
00:13:40
third-party weather API gives us
00:13:42
information in Celsius in kilometers and
00:13:45
I've created this weather API interface
00:13:47
however our app is expecting Freedom
00:13:50
Units of Fahrenheit and Miles without an
00:13:53
adapter we'll do something like this
00:13:54
create implementation of thirdparty API
00:13:56
with class thirdparty weather API that
00:13:58
implement weather API which is the
00:14:00
getting our Celsius and getting our kilm
00:14:03
per hour and then in order for it to
00:14:05
work in our app we would have to come
00:14:06
down here create the new thirdparty
00:14:09
weather API stored in weather API and
00:14:11
then do the conversion from Celsius to
00:14:13
Fahrenheit conversion from kilometers to
00:14:15
miles and well that's what you'd have to
00:14:16
do every single time however with the
00:14:18
adapter we implement the weather app
00:14:21
which is what has temp F and speed miles
00:14:26
hour we'd create class weather adapter
00:14:28
that implements weather app which has
00:14:30
our freedom units in Constructor private
00:14:32
weather API weather API and then in our
00:14:35
Constructor we say hey weather API
00:14:37
interface we need you because we're
00:14:39
going to get the temp c from that
00:14:42
weather API we're going to convert it to
00:14:44
Fahrenheit and it'll be all done in this
00:14:47
method and same idea with kilometers to
00:14:50
miles and all of this is being done
00:14:52
within the class so when we want to get
00:14:54
that information from our API we can do
00:14:56
something like this all of the logic is
00:14:59
hidden right here and then we're using
00:15:01
that information oh is it above 75 oh
00:15:04
it's hot oh is the wind speed above 10
00:15:07
mph oh it's windy that's it so instead
00:15:10
of changing your code everywhere and
00:15:13
putting that logic every single time you
00:15:15
need to use celsius and kilometers from
00:15:18
the weather API or if it was a library
00:15:20
trying to modif modify the entire
00:15:22
Library good luck with that all you have
00:15:23
to do is wrap it in and adapt sounds
00:15:26
like I was almost saying rapid Dash wrap
00:15:28
it in and adapter rapid in an adapter
00:15:31
say that five times fast the only thing
00:15:32
is it can get real tedious trying to
00:15:34
make an adapter for everything best case
00:15:37
scenarios that your library and API
00:15:38
match up with what your app needs but
00:15:41
that's again that's not always the case
00:15:42
and an adapter is always going to be
00:15:44
better than having all of this logic
00:15:46
spread throughout your entire code base
00:15:48
and what's interesting about the adapter
00:15:50
pattern I don't know if this is just my
00:15:52
mind trying to connect things but since
00:15:55
it's all about making different
00:15:57
implementations work together through a
00:16:00
common
00:16:01
interface it's kind of like the
00:16:03
application of the strategy pattern
00:16:05
which is the first behavioral pattern
00:16:07
we'll be discussing and just to clarify
00:16:09
again the structural pattern is how
00:16:11
objects interact with each other
00:16:13
behavioral patterns is exactly how they
00:16:16
behave how they communicate with one
00:16:18
another so let's talk about the strategy
00:16:20
pattern think about how you get to work
00:16:22
some days you may drive to work other
00:16:24
days you may ride your bike to work
00:16:25
other days you may ride the
00:16:27
bus I I live in the middle of nowhere
00:16:30
where we don't have public
00:16:31
transportation nor am I close enough to
00:16:33
ride my bike anywhere so I just I do
00:16:35
drive everywhere but this is how I
00:16:38
imagine city Folk do it oh let me change
00:16:40
it up today let's take the subway today
00:16:42
let's take the train let's let me drive
00:16:44
let me bike let me walk I don't know
00:16:47
regardless what I'm trying to get at is
00:16:49
uh you have a common goal you need to
00:16:52
get from point A to point B you are
00:16:54
trying to get to work you just have
00:16:56
different strategies of going about it
00:16:59
one is driving one is walking one is
00:17:01
taking the bus that's exactly what this
00:17:02
pattern is all about so without the
00:17:04
strategy pattern you have the efl's
00:17:06
nightmare you have a class of commuter
00:17:08
that's you you're the commuter and you
00:17:10
are going to work and if you're
00:17:12
transport car then you know you got to
00:17:14
start car check gas navigate traffic
00:17:16
parking garage all of the logic is here
00:17:18
else if you're taking the bus this logic
00:17:21
taking the bike that logic and then this
00:17:24
keeps growing with each transport type
00:17:26
however with the strategy pattern you
00:17:28
just have an interface of Transport
00:17:31
strategy and then you implement
00:17:33
transport strategy in the specific class
00:17:35
foreset strategy so car strategy you put
00:17:38
in the car specific logic bus strategy
00:17:41
same idea bike strategy same idea so
00:17:43
that way once you come down here and
00:17:45
actually create a better Commuter class
00:17:48
within the class you can set the
00:17:50
strategy and then just have one single
00:17:53
if statement that utilizes whatever
00:17:55
strategy you set up here and runs this
00:17:58
Logic for for all of them and again
00:18:00
instead of having if else if else if and
00:18:03
then keep on going for walking and
00:18:06
Subway and this and that so the usage
00:18:08
would be just like this with the better
00:18:10
Commuter you would store that in
00:18:11
commuter and then you could set your
00:18:13
strategy to car strategy and then just
00:18:15
call go to work and it'll do all of that
00:18:17
logic with thing go to work and then if
00:18:19
you need to switch the strategy let's do
00:18:21
bike strategy instead that's how we're
00:18:23
going to set the strategy and go to work
00:18:25
with bike strategy and that's where
00:18:27
again each individual strategy has their
00:18:30
specific logic within it it is just so
00:18:34
much cleaner this is how you need to be
00:18:36
writing code don't don't don't if else
00:18:39
if else if else if El every single time
00:18:41
because the beauty of the strategy
00:18:43
pattern is that it it allows you to
00:18:45
define a a family of algorithms you put
00:18:49
each into its own class and then make
00:18:51
them completely interchangeable or in
00:18:54
other words it's just a fancy way of
00:18:55
saying programming at an interface level
00:18:58
letting you swap implementations without
00:19:00
you needing to change any of your code
00:19:02
you just make the thing into an
00:19:03
interface and you do all the logic below
00:19:05
the interface when should you use it all
00:19:08
the time if you got different ways of
00:19:10
doing the same thing then the strategy
00:19:13
pattern is going to be your best friend
00:19:14
it follows the open closed principle
00:19:16
perfectly you can add new strategies
00:19:18
without touching any existing code and
00:19:20
again that is just creating a new class
00:19:22
that implements the transport strategy
00:19:24
is whatever strategy we have car bus
00:19:26
bike walk strategy and implement the
00:19:29
transport strategy have your logic
00:19:31
within that class the the walk strategy
00:19:34
class you're good the downside downside
00:19:36
is that you end up with a bunch of
00:19:37
classes but that's a whole lot better
00:19:39
than if eling if eling if eling and
00:19:43
having the logic here and then having 20
00:19:45
different small classes all with their
00:19:48
own L statements like I was just saying
00:19:51
yeah I'm going to take the strategy
00:19:52
pattern every day of the week and I know
00:19:54
I know this is going to hurt some
00:19:56
feelings because I know a lot of y'all
00:19:58
are just if elsing if elsing everything
00:20:01
you know who you are don't you know who
00:20:03
you are all right the last but not least
00:20:06
the Observer pattern and I'm going to
00:20:08
use the you a YouTube example because
00:20:10
you're watching this on YouTube and
00:20:12
you're the Observer to my video but
00:20:15
let's focus on like notifications when I
00:20:16
upload a video and you're subscribed
00:20:18
actually when you click the Bell make
00:20:20
sure you click the Bell make sure you're
00:20:22
subscribed all that when you click the
00:20:23
bell I upload a video you get notified
00:20:26
that's it the Observer pattern in code
00:20:29
we'll go over it lets objects subscribe
00:20:32
to events that happen to other objects
00:20:35
objects subscribe to events that happen
00:20:37
to other objects so here's the code
00:20:39
without the Observer you have a class
00:20:41
called user account this is the class to
00:20:44
create you the user and right down here
00:20:47
you create the user account array and
00:20:50
you are put in an array with all of the
00:20:52
other subscribers of this video channel
00:20:55
right and then when I upload a video
00:20:57
what do I want to do I want to bloop
00:20:59
through users and notify you somehow
00:21:01
that 500 600,000 of y'all I don't think
00:21:05
so so instead we use the Observer so
00:21:08
that subscribers get notified
00:21:10
automatically same idea but we create an
00:21:12
interface called subscriber and then
00:21:14
we're going to create a class we I just
00:21:15
called it better video channel just so I
00:21:17
can have two video channel classes in
00:21:19
here and it is the same idea we have the
00:21:22
subscriber array and then you are added
00:21:24
when you subscribe or removed when you
00:21:27
unsubscribe and then when I upload a
00:21:29
video we would notify with the title of
00:21:32
the video to the subscribers down here
00:21:35
as you can see this is our private
00:21:36
notify method and we pass in the title
00:21:39
so that it notifies all of my
00:21:41
subscribers each of my subscribers I
00:21:43
should say with that information does
00:21:45
that make sense I think it's a good
00:21:47
example it's just a little as long as
00:21:50
you know how to read code you know
00:21:51
exactly that it makes sense otherwise
00:21:52
you're going to have to Loop through
00:21:54
millions and millions of people for many
00:21:56
other channels every single time you
00:21:57
upload a video which is not very uh
00:22:00
performant so this in code like you see
00:22:03
how it works in the code here but this
00:22:06
could be like uh servers looking for
00:22:09
system errors or monitoring for them so
00:22:12
anytime there's a system error boom it
00:22:14
gets notified or a component listening
00:22:16
for uh State changes so remember object
00:22:20
subscribing to events that happen to
00:22:22
another object now there is one gotcha
00:22:24
though if you uh well if you go
00:22:27
overboard on a vent
00:22:29
you could enter into what is known as
00:22:31
event callback hell where one event
00:22:33
triggers another event which triggers
00:22:35
another event and then all of a sudden
00:22:37
you're wondering why your app is sending
00:22:39
you a notification from 3 weeks ago but
00:22:41
use responsibly The Observer pattern is
00:22:44
is an amazing way to handle the uh if
00:22:48
this happens do that and there you have
00:22:50
it like any good tool it's knowing when
00:22:53
to use each one so study them use them
00:22:56
practice to get them in GR in your head
00:22:59
for more programming Concepts and
00:23:03
developer stuff explained with too many
00:23:05
analogies make sure you subscribe to the
00:23:07
channel I'll see you in the next one