
do a little continuation on last week’s
video which was about doing dependency
injection in JavaScript without using
classes
I am mpj and you are watching fun fun
[Music]
I am back at home and it feels so good
if if you’re wondering about my hair
the this is my stage hair from Nordic
jazz do you like it mm-hmm
which I have been hosting co-hosting
last week and it has been weird this
week because I’m recording this on
Sundays and it was amazing amazing
amazing but it was also probably one of
the hardest pieces of work I have ever
done
Jesus it was so intense some fans showed
up and gave me Serbian candy I I suppose
it’s not a good idea to eat stuff from
random people on the internet but it’s
free package so I think it’s fine if I
die this will be proof it’s this is from
the manga thank you new manga I at least
I’m pretty sure it wasn’t a man John the
think was things were pretty hectic at
anyway last week we explored how to do
dependency injection without using
classes in JavaScript and today I would
like to continue exploring this but with
some more sophisticated examples and
also discuss a little bit about
architecture here is the example that
was in the beginning of last week’s
video I just to very quickly remind you
this was a class user manager it takes a
database connection we inject that here
in the constructor and then the there’s
a create user method which uses this
connection to access the table users and
insert and you use it with some
properties that I made up and then it
returns the user ID exactly what this
code does is not important the important
part is that it’s dependent on this
database connection line we want to
inject that so that we have control over
our dependencies and we can test them
and then we refactor this code too
instead of using a class using a set of
nested functions and we okay so this
does exactly the same thing by having
this creating this factory function
which creates the make use of function
and uses a closure to pass the passer
connection dependency instead of using a
instead of using class properties so
that is what we did but what I would
like to discuss today is if I ask
control-z back to our original example
there what if we had more than one
method here let’s say we just invent one
the lead user and we call it needs an ID
there and let’s just make up some
implementation all right so now the
situation has changed a little bit
because we now have these both these
methods are now making use of this
dependency so we are sharing the
injector dependency between these two
these two class these two methods and
this represents what we are going to
explore today this sharing of
dependencies between between functions
I’m going to show you how to do this
without using without using classes but
I’m also going to discuss a little bit
of about why you wouldn’t want to do do
this kind of sharing what are the
caveats with it we’re like when should
you do it and when shouldn’t you Oh
increase the font so it’s a little bit
all right let’s go back to the fun
shanell example here bloop bloop well
this is the same one as before
and let’s add a the delete user
equivalents delete user and it was a
connection and a name and it was
something like this oh it was an ID
right something like that this exact
exact implementation it’s not at all
important what we are concerned with is
this relationship here okay so let’s
think about how we use these things this
is the example from the last episode
this is the file that we were just
editing and we are pulling in make
create user because that already existed
there now let’s also troll in make
delete user that we had and then we will
use make delete user to create the
actual make delete function launched
sorry delete user make use connection
all right so what we see here is a
little bit of duplication that will
disturb your eye a little because as
programmers we are trained to look at to
click look for duplication and and
remove it
I often talk about how you should be
very careful about removing duplication
you should absolutely do it but you
should do it defensively and wait for a
lot of duplication to our eyes before
removing it because otherwise you will
probably miss identify the actual
pattern and you will generalize
incorrectly we will be talking about
this during the course of this video and
in many examples but for now let’s
imagine that we actually want to remove
this duplication let’s not
that we have some more examples of this
let’s say that perhaps we had hmm I’d
say that we had make up date you sir and
perhaps make ban you sir as well so now
we are starting to see some some
duplication here we are going to be
removing this but first I would like to
draw your attention to the fact like
this dependency is very easy to see now
like it’s very clear how the
dependencies flow and they act at the
moment there’s some duplication sure but
it’s still very easy to see and reason
about it’s very simple but let’s play
around a little bit with some higher
order functions if your are higher order
functions it’s a bit fussy concept to
you I have a video on that there that
BAM so this is the exactly the same so
you see here that this thing here we
have replaced that with by using a map
here so basically we have taken all of
these here put them in this array which
is called factories and then we map what
map over the factories here and for
every factory we call that factory where
the connection object and that will give
us an array and then we use
destructuring here to extract that into
variables so now we can just call like
create user and Joe Smith here or delete
user one two three if this syntax here
is new to you this is called
destructuring it’s a new feature in
JavaScript you can check out my video on
destructuring here this is pretty cool
but we are doing way too much prediction
of the future here we are assuming that
all all functions will have the same the
same set of dependencies which is not
true let’s say that ban user also
required an email service so yeah we
could inject all of the dependencies
into all of the all of the functions
this becomes a little bit weird it’s not
completely unreasonable oh I guess that
we could just inject all dependencies as
as an object into all like inject all
all dependencies into all factories but
seems to me that we kind of want an
a little bit more control this seems
let’s try another way okay so we know
I’m not gonna write email service out
you can imagine that it’s just the same
thing as this connection but instead of
unicron DB vendor perhaps it’s some
email service vendor and we do some
instantiation here and then pass it in
to ban user M okay how do we proceed you
all right so instead of these imagine
that we had a make user utils function
and you called that make user utils you
know what I’m gonna comment this out to
leave it for comparison and we’re going
to pass in the dependencies connection
in mail service and that is going to
give us an an object that we will be
let’s go back into use of utils and have
a look wow I see that I actually made a
mistake here a confusing mistake it
should be make delete user here because
this is a factory that creates the
delete user delete user is this function
here and this whole thing here that is
make delete user or this you can take
with us I think creating the liddie the
delete function use delete user function
anyway let’s refactor this a bit we are
instead we want to export the salt and I
colonists I want to make user you chills
oh we can’t export a constant we have to
do this first make use of you tools and
you see utils and that takes an object
with dependencies and those dependencies
are connection and mail service I think
it was called and that will just return
an object more there we go and these are
no longer our factories they are these
are the actual functions because they
all now have access to the connection
object here I’m gonna do the same thing
with delete user I don’t and colon
instead there delete that and export the
fault make user you just so exporting
that Oh indentation should be right so
now we are making this like instead of
having a factory oops
for every every function we now have
this sort of like
rapping factory for for all of them at
the same time so that they share the
scope the closure scope here so that
both these functions here have access to
the connection object so this way we can
also create the ban user function I
guess it takes an ID and then there’s a
connection dot table users let’s call it
update something hang on
and I bet that takes a delta so let’s
say that it’s I know MongoDB syntax here
something like bad true I don’t know I’m
making this up as I go and when the
update is done it should call the mail
service we don’t have the email yet here
that we would have to figure that out it
not that way that’s not really relevant
to the example let’s just say Joe yeah
come and I banned you dude busted
operator from hell
alright so you see here now that this
has access to mail service this has
access to these have access to the
connection and if we go back remember
how it was used we just pass in the
dependencies here as as an object
literal and it can access them and then
it creates all of these in one fell
swoop for us
notice that this pattern is very similar
to a class where with some constructors
let me let me just drop up the class
sorta so here we would just have let’s
say
you source our mail service now we would
go this dot mail author mail service
course mail service something like that
and then we would do the same
implementation here and but instead of
using the the closure of the function
like it did here it would you see these
properties on the on the instance
instead but essentially the two patterns
are very similar it’s just that this
uses just functions and closures instead
of the class construct a problem with
this pattern is that we are over sharing
so mail service the it’s very nice in
this case when connection is used by all
user utils here but mail service is only
used by a few so that means that this
mail service here is being exposed to
and passed into all of all of to both
create user and delete user even though
they have no business knowing about that
this is not exactly a cardinal sin but
it can be problematic partially because
the dependencies are now less less
obvious for example before we could look
at in this case here if we go back to
the app here we can see exactly what
dependencies each thing has but here
this has now become slightly more
obscured from us dependencies are
starting to become this this blob of
things also even if you look in the
class the whole dependencies chain is a
bit when when you see something like
this with a group here it kind of makes
a person that that starts working in
this this class or this whatever we call
it module
it makes them think it’s okay to use the
mail service which it might really not
be make like this is this is just its
own thing here like just because
something is in this utils file doesn’t
make mean that it’s sensible to start
accessing accessing the mail service so
this this grouping here is starting to
become a little bit problematic speaking
of the grouping becoming a programmatic
it also becomes problematic in another
way it’s that user utils like it was
just something that we started doing
because when we had a create user we put
that in some file or some class and we
just figured that that file or that
classic needed a name and then it became
use of utils and it felt like okay this
is the place where we put crud
operations for for users but once we
start actually doing things we realize
that hey we actually need functions that
do quite a bit of things so such as
mailing mailing users or perhaps if we
are deleting users perhaps then we need
to do something with payment information
or billing information or whatever we’re
not quite sure what this what what this
this group of things is because we have
created the group prematurely before we
we actually know where we were going
it would have been better to just have
kept all of these these functions like
isolated and let them live their own
lives and let a pattern emerge before
starting to group them because when you
start grouping things it becomes harder
to an unentangled them and it also makes
communicate something to other
programmers that oh this is a creative
group but it’s really not we have just
it’s just starting to get group by what
dependencies they have which is not
really a good and sensible way of
grouping thing
to be honest like you want to group
things in are like there are many other
much better ways cohesive ways to group
things then what dependent what they
depend on but it becomes the consequence
if this is this is what we do breaking
things into modules based on based on
their dependency set I want to really
drive this home like it when I let’s go
back to the class example here when when
we started created to create user here
and we had to create a a class let’s
imagine that we were in a language like
Java where everything is required to be
a class then to whenever you create a
function you also need to create a
wrapping class and this creates an
interesting problem because we know what
we want to do we know that we want to
insert a user into the database and we
five-five find the side that create user
is a sensible name to do that however
java would also force us to name this
thing
this class is group this group of one
and there’s a subtle sinister thing
about that and it’s that portal it’s
distracting because we have to name one
other thing and naming is hard and
time-consuming
there’s a there’s an old joke in
computer programming saying that was it
now there are only two hard problems in
computer science concurrency and naming
things like many things hard takes time
and here you are forced to do that even
though it’s not really required we just
wanted to create a function and also
we’re the naming the reason why naming
is is so hard is that it requires you to
predict the future it requires you to
think about what will come next here and
because you really have no information
you have just one piece of data or just
perhaps a few it’s just too
for you to make that decision this is
not it’s not sensible to do that this
early you should wait for more
duplication and instances of something
to arise before generalizing or starting
grouping and organizing in order to
group and generalize or whatever you
need to see a pattern you need to know
what the general pattern is and if you
if you don’t let duplication rise first
you are going to invent too much of the
pattern in your head and you are going
to predict the future incorrectly or not
going to but in probably you’re going to
be wrong and since this is something
that we do a lot we should we should
rely on probability this is actually a
great example of one of the main reasons
why I dislike object-oriented
programming I feel that it incentivizes
you to predict the future at an earlier
point than you are able to do it well
this what we do here like making this
use you tools in a real lab this is not
what I would do at the moment when I’m
programming I guess the the reason why
we ended up with you three tails was
that I wanted to create something that
had a good one to one mapping with the
initial class example in in a real app I
something I I don’t know other services
or something and then I would like just
do something like this and then I would
import them from there oh no sorry like
it would be make create user and make
delete user and make update user and
make van user and then I would just have
this sorry this huge file let me go back
here to where we were before
LLL learn like this and the file would
look like this and I would just dump
into this other category until I
started figuring out very clear patterns
on an organization and then and only
then I would start creating something
like would be like oh I don’t know
account services or something where I
start putting things like the user flow
things I don’t know like that’s a point
I don’t know I do you don’t know how an
application will be structured or what
sense
what structure makes sense for an
application until you are quite a bit of
time into it so I’m a big fan of have
programming your architecture
defensively so that you can let
structure emerge as the patterns emerge
and become clear to you I have tried so
many times to do upfront architecture in
an application and it has literally
never worked it never works because
humans are not particularly good at
predicting the future our brains are
wired to like they are designed to plan
movements like you we are designed to
like okay if I walk behind that rock
then perhaps there’s a lion I need to
watch before the line our brains are
basically for planning movements and
predicting the architecture of a
software software application that is
that is way too complicated for our
brains so let duplication arise in in in
high quantity if possible instead of
trying to predict what that pattern will
be and that is what I want to talk about
today I wanted to show you how you can
share dependency
between functions when you are doing
dependency injection without without
classes but I also wanted to talk about
the problem with sharing dependencies in
general and how you should try to wait
for patterns to emerge and be clear
instead of trying to predict the future
upfront you have just watched an episode
of fun fun function I release these
every Monday morning Oh 800 GMT you can
check out another episode here if you
have questions thoughts around this
episode you can check out this topic on
the Fun Fun forum that is dedicated to
this episode I am mpj until next Monday morning say curious