Inversion of Control - Fun Fun Function

แชร์
ฝัง
  • เผยแพร่เมื่อ 22 ต.ค. 2024

ความคิดเห็น • 175

  • @DavidWhitman1990
    @DavidWhitman1990 7 ปีที่แล้ว +50

    I love that DI and IoC were split into separate videos. The two so often go hand-in-hand that I didn't really know where one ended and the other began.
    Also, great overview of what the js code does.

  • @autochton
    @autochton 7 ปีที่แล้ว +49

    With ES2015 arrow functions, partial application can be accomplished very neatly:
    function storeDocument (dep1, dep2, dep3, arg1, arg2) { /* do things */ }
    const createStoreDocument = (dep1, dep2, dep3) => (arg1, arg2) => storeDocument (dep1, dep2, dep3, arg1, arg2);
    Now, createStoreDocument, when called with the three dependencies dep1 - dep3, will return a function, which when called with arg1 and arg2, will call storeDocument with all its needed arguments.

    • @brawndo8726
      @brawndo8726 5 ปีที่แล้ว

      You just blew my brain...

    • @brawndo8726
      @brawndo8726 5 ปีที่แล้ว +2

      At this point, would there be a point in doing his 14:00 trick of passing destructured dependencies?
      As in storeDocument( {dep1, dep2, dep3 }, arg1, arg2 ) {...
      Maybe for the sake of clarity?..

    • @scycer
      @scycer 4 ปีที่แล้ว +1

      Lol this is the first thing i thought when i saw the factory func, "Ow its partial application to keep the scope in play"

  • @eltucangaming8332
    @eltucangaming8332 ปีที่แล้ว +1

    It feels good to watch you again, my friend, after all these years

  • @Stanelu13
    @Stanelu13 7 ปีที่แล้ว +8

    After watching every video about JS you have 3-4 times and actually practicing what you teach I have managed to land a job I never though I could. I owe you for this.
    Keep the good work going!

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +5

      +Stan George Thank you so much for writing this, makes my day!!

  • @ArturGrigio
    @ArturGrigio 6 ปีที่แล้ว +1

    @MPJ 's videos are like those movies that have infinite re-watchability.
    I re-watch these videos to go over definitions of concepts I use on daily basis, but don't care enough to memorize the "Why". And every time I re-watch it, there is a new caveat that becomes clearer :)
    Tx MPJ :)

  • @nicolasiensen
    @nicolasiensen 7 ปีที่แล้ว +14

    I like the way you improved the isolation of the storeDocument function.
    Nevertheless, in my opinion, this function is responsible for too much logic. The storeDocument function is:
    1) fetching the user and the folder location from the database
    2) verifying if the user is allowed to write in the given folder
    3) then it is actually doing what it was suppose to do
    I would investigate how to extract the steps 1 and 2 from the storeDocument, and leave the function responsible for just the 3rd step.
    Great job Mattias!

  • @andrewjakubowicz6252
    @andrewjakubowicz6252 7 ปีที่แล้ว +1

    This was a fantastic video. I've struggled with this problem myself, and seen people use factory functions... however I didn't grok it until now. Thank you mpj!

  • @kauanmocelin
    @kauanmocelin 4 ปีที่แล้ว +2

    You did a great explanation about the separation of concerns using IoC. Thanks dude.

  • @ciukstar1981
    @ciukstar1981 6 ปีที่แล้ว +1

    Inversion of control is transferring control from library to the client. It make more sense when we talk about a client that injects (passes) a function value (lambda expression) to a higher order function (library function) that controls (changes) the behavior of the library function. A client or framework that injects dependencies (which carry behavior) into libraries may also be considered IoC

  • @floverdevel
    @floverdevel 7 ปีที่แล้ว +2

    Really love the «Batteries included function» expression :)
    i'm gonna use it to help me explain the concept to others ...

  • @gpluta
    @gpluta 7 ปีที่แล้ว +2

    Another great episode! Thanks for that!
    It would be really great to see some more content on design patterns. It is a great way to expand your thinking about programming.
    Cheers!

  • @LeoCavalcantee
    @LeoCavalcantee 7 ปีที่แล้ว +8

    I think that another problem to check on is the fact that `storeDocument` violates SRP doing a little more than just storing a document.
    Maybe the responsibility of fetching an user, a folder and checking for write-access should be extracted to the entrypoint/consumer/main.
    Also, imagine a scenario where you want to store two or more file streams for the same user ID and in the same folder, if you call `storeDocument` twice or more it will fetch I/Os again for the same data.

    • @rebornreaper194
      @rebornreaper194 6 ปีที่แล้ว

      Bingo

    • @peterfarr9591
      @peterfarr9591 5 ปีที่แล้ว

      The SRP doesn't actually mean that every module has a single purpose - if you read "Clean Architecture" it's explained that SRP actually means that "A module should be responsible to one, and only one, actor". By actor what is meant really is "department." If you work at a company you should design your modules so a module would only have a request from a single department head (CTO, CPO, CFO etc.) to CHANGE. That might still be true in this example, but you are misrepresenting the point of SRP.

  • @gorannovaks
    @gorannovaks 7 ปีที่แล้ว

    quality of video: shots, colors, even content becomes even more fascinating with the new iteration **w** evolution, it works))

  • @lpaulger
    @lpaulger 7 ปีที่แล้ว +5

    This is a wonderful explanation on how to separate concerns! One thing I'm struggling to reason about is if I need to unit test my factory functions? In my case, and with yours, the StoreDocument would have their own "creation" tests inside its own unit testing file. thoughts?

  • @spacedoohicky
    @spacedoohicky 7 ปีที่แล้ว +1

    Pretty cool. With es2015 you can use functions as default parameters so this will be even easier to do. Which also means dynamic dependency injection so you can have inversion in your inversion. ;P

  • @wahoobeans
    @wahoobeans 9 หลายเดือนก่อน

    When I used to be really into unit tests, I just get into the habit of importing the same dependencies into the test file and then defining the a mock for each dependency.
    As an alternative to inversion of control and dependency injection pattern specifically into the function signature. Like just move the dependency into another file and then mock it.

  • @stevenfrieson3228
    @stevenfrieson3228 7 ปีที่แล้ว

    Ugh... I wish I knew this before. Time to refactor. This is going too be super useful going forward. Thanks!

  • @francofumo
    @francofumo 7 ปีที่แล้ว

    Dude. You're so good at this. Thanks for the informative and easy to watch episode!

  • @nayaleezy
    @nayaleezy 7 ปีที่แล้ว +1

    you fabulous man, destructuring, and fat arrow scoping are a few of my favorite things

  • @gomtv5383
    @gomtv5383 7 ปีที่แล้ว +1

    Was hoping this weeks video would cover this topic!

  • @democrito85
    @democrito85 7 ปีที่แล้ว

    MPJ, hello!
    I have a neat little trick of testing my node.js code, I'm not sure if it is good, but it works wonders at least for me and my needs, and allows me to inject whatever I want, even arguments in callback functions and so on.
    I called it simply context injection, and I made it specifically for testing and error dumping, using this thingy allows me to have 100% code coverage very easily.
    Would you be interested seeing it and maybe doing a video criticizing this design? I would love to see what you think about it and where this design can be improved.

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      +Anon I'd love to, send a link or something.

    • @democrito85
      @democrito85 7 ปีที่แล้ว

      Here is a small example of how it works, I hope you get the idea hehe
      gist.github.com/ubirajaramneto/a93f325290c1119dde0a90f7f6b34513

  • @michalsnik
    @michalsnik 7 ปีที่แล้ว

    Great video Mattias! Keep it up. IMO Next should be about "Dependency Inversion". Those terms (Dependency Injection, IoC, Dependency Inversion) are constantly mistakenly perceived by lots of people.

  • @augustcom
    @augustcom 7 ปีที่แล้ว

    I would have liked the font of the code to be a few points larger, as I'm always watching this on my phone every Monday morning! :)

  • @NathanSherburn
    @NathanSherburn 7 ปีที่แล้ว

    Another great episode! Clarified a lot for me. Thanks MPJ!

  • @CodyeWatson
    @CodyeWatson 6 ปีที่แล้ว

    Best quote ever! - "From the views point-of-view." 16:37

  • @namirsayed-ahmadbaraza8970
    @namirsayed-ahmadbaraza8970 7 ปีที่แล้ว +3

    hey mpj! thanks a lot for the channel!
    I wanted to ask you one thing, I've always thought IoC was what every framework does, basically providing functions and components that are called by some sort of controllers (the framework) and it's related with dependency injection because that controller inject dependencies into your components. I just wanted to know if this is related. thanks!

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      +Namir Sayed-Ahmad Baraza yes, that is a correct observation.

    • @namirsayed-ahmadbaraza8970
      @namirsayed-ahmadbaraza8970 7 ปีที่แล้ว

      Thanks.
      So in that video you are explaining what a "framework" would do internally to inject dependencies?

  • @damuz_yt
    @damuz_yt 7 ปีที่แล้ว

    The beauties of functional programming, honestly I didn't get the whole thing but I'll forgive myself because I'm still pretty new to the real programming world, I'm a front end web developer (intern) so I try to learn as much as posible from your content, Greetings!

    • @naythaniel
      @naythaniel 7 ปีที่แล้ว +2

      I know functional programming is super en vogue in javascript proselytizing recently, but the factory pattern is a general programming concept (used in both oo and functional) and you can find a lot of information about it in books like "Javascript Design Patterns" addyosmani.com/resources/essentialjsdesignpatterns/book/
      or any other book about programming design patterns in pretty much any language.

    • @damuz_yt
      @damuz_yt 7 ปีที่แล้ว +1

      Naythan Williams Naythan Williams well thanks for the clarification, I'll definitely take a look at some design patterns I just thought that the code fitted very well on the functional programming paradigm because of the way he is manipulating the data in functions, Greetings from Mexico :D

    • @rothbardfreedom
      @rothbardfreedom 7 ปีที่แล้ว

      What we have of FP here is the partial function application in the store documents factory.

    • @naythaniel
      @naythaniel 7 ปีที่แล้ว

      Lizardan Your statement about partial application is incorrect. The reason why is a bit too long for this comment, but this article goes into more detail. medium.com/javascript-scene/curry-or-partial-application-8150044c78b8#.wmfiaedod

    • @damuz_yt
      @damuz_yt 7 ปีที่แล้ว

      Is it also correct to say that this functions are "pure" ? Because all the data manipulation is happening inside each función ?

  • @stevepascoe
    @stevepascoe 7 ปีที่แล้ว +2

    Move over Uncle Bob 😁
    Great too seeing an IoC example in everyday js. 👌

  • @VipulAnand751
    @VipulAnand751 7 ปีที่แล้ว

    Interesting to learn the concept of "batteries included"

  • @bhuvanesh94
    @bhuvanesh94 7 ปีที่แล้ว

    It was really an helpful video. Thanks for the effort that your taking for making viewer to understand the point. 👍

  • @fraklopez9521
    @fraklopez9521 7 ปีที่แล้ว

    Fantastic episode MPJ!
    Considering the code you were given, would this be what you would have done normally? Would you instead try to refactor it into separate functions or perhaps something completely different?
    Thanks and awesome shirt btw!

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      +Frak Lopez thanks for noticing the t-shirt!
      In the video, I wanted to focus on just one improvement aspect, but another viewer offered some interesting improvement suggestions to the original code here: gist.github.com/mpj/c55dc66bc2cfd389dbbd25ab5092d4f3#gistcomment-1980823

    • @fraklopez9521
      @fraklopez9521 7 ปีที่แล้ว

      Your focus in these videos is what makes them great! You make videos like good code. You focus on a single thing then use composition (by referring to other videos you made) to accomplish more. :)
      When I saw the code in the video, my first thought was to refactor it quite differently. I was just curious if this approach was your natural response or if you just did this to explain Inversion of Control?
      In any regard, thanks for being awesome!

  • @sta_____rk
    @sta_____rk 4 ปีที่แล้ว

    This is a good topic to elaborate on.

  • @SuperManitu1
    @SuperManitu1 7 ปีที่แล้ว

    Thats why I love Cycle.js, your whole app is pure, so you dont need to inject anything. Unit testing is a breeze

  • @sabres2077
    @sabres2077 3 ปีที่แล้ว +1

    Is there a reason why you used bind instead of a closure?

  • @DouglasWright
    @DouglasWright 7 ปีที่แล้ว

    Another great video...with a nice production example. Great job!

  • @TheFlamePhoenix
    @TheFlamePhoenix 7 ปีที่แล้ว

    Dear mpj, I have a question regarding dependency injection and inversion of control. Two main things pop to my head:
    1. Instead of injecting dependencies via parameters, why not pass an object with all the dependencies we want? Simple (quite old) example: stackoverflow.com/questions/27735855/javascript-function-with-optional-parameters-as-object
    2. Instead of using inversion of control with bind, why not use ECMA5 object destructing?
    developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
    I made a small example demonstrating my thoughts:
    dog.js - pastebin.com/ct1ST5bN
    index.js - pastebin.com/D6KhYJ3T
    The whole inversion of control thing seems out of date. What are your thoughts, how would you make this testable?

  • @Russ_Paul
    @Russ_Paul 4 ปีที่แล้ว

    Great tutorial! Question, is createStoreDocument in essence an interface?

  • @vhuerta
    @vhuerta 7 ปีที่แล้ว

    I think its a good example, what do you think about this idea: wrap the function on a JSON object with an init method and then the factory function can use the method Object.create, like this:
    // lib.js
    const lib = {
    init(userDB, folderDb , userAccess) {
    this.userDB = userDB;
    this.folderDb = userDB;
    this.userAccess = userAccess;
    return this;
    }
    storeDocument(userId, folderLocation, fileStream) {
    return Promise.all([this.userdb(...), this.folderDb(...)]);
    }
    }
    // factory.js
    // IMPORTS
    const factory = () => Object.create(lib).init(importedUserBD, importedFolderDB, importedUserAccess);
    // Usage
    factory().storeDocument();
    i know than if the function is bouded in another context the reference of this will be lost, but do you think is a cool idea?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      I like it!
      That the reference to this is lost in other contexts is inevitable if you use the prototype, so I would not worry about that. Any attempt to circumvent is nonsensical, since that will just end up creating solutions that are less performant that revealing module and other patterns that use closures.

  • @nickbaughan1803
    @nickbaughan1803 7 ปีที่แล้ว

    Great video. Have you thought about(or did and I can't find it) doing one on the open closed principle?

  • @楊侑寰
    @楊侑寰 4 ปีที่แล้ว

    Thanks for the explanation. It is really really helpful!

  • @Kevbac00101
    @Kevbac00101 7 ปีที่แล้ว

    It might be a dumb question, but : How do I test the storeDocumentFactory (or createStoreDocument) function ?
    I just test that it returns a function with given arguments included ? Is it possible ? Do I need to ? (because inside this factory, it is possible to have some logic too I guess)
    BTW love your videos, keep going it helps me a LOT ;)

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +2

      You do not unit test storeDocumentFactory. Well, you CAN, but it doesn't really make sense to write unit tests for code that has just one execution path and will most likely never get a second. You're effectively unit testing configuration then, which is just writing things twice, which adds more hassle than it adds security.
      I view storeDocumentFactory as a kind of integration point in the app that is implicitly covered by System Tests (i.e. click-around-in-the-app tests). If you've written something wrong in storeDocumentFactory the app will generally break on startup or one of the basic cases, so you're not likely to make undiscovered mistakes in that place.

    • @Kevbac00101
      @Kevbac00101 7 ปีที่แล้ว

      All right. I got it, thank you for your answer !

  • @mindbodysouldeveloper9688
    @mindbodysouldeveloper9688 7 ปีที่แล้ว

    Excellent explanation. Love it.
    My only question is: Where are the coffee breaks? :)

  • @benjaminmosnier
    @benjaminmosnier 7 ปีที่แล้ว +3

    I am a little confused by the "return storeDocument.bind(null, userDB, folderDB, userAccess, fileStorage)" line...
    not about the null, but more about the multi arguments following...
    could you be more verbose on the point ?
    thank you

    • @krzysztofkabat9166
      @krzysztofkabat9166 7 ปีที่แล้ว +8

      Benjamin Mosnier
      this bind will create a new function just like that storeDocument except first 4 arguments will be filled in. Therefore this new function "remembers" those arguments every time it is called, and when you call it you just need to provide only missing arguments.

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +20

      It creates a new function that is the same as storeDocument but where the first arguments have been "pre-installed" so to speak. Check this out:
      greet('hello', 'benjamin') // Hello, Benjamin!
      let goodAfternoon = greet.bind(null, 'good afternoon')
      let goodbye = greet.bind(null, 'goodbye')
      goodAfternoon('benjamin') // Good afternoon, Benjamin!
      goodbye('waffles') // Goodbye, waffles!

    • @pmrcunha
      @pmrcunha 7 ปีที่แล้ว +5

      I'll give it a try at explaining this:
      bind assigns values to a function's this value and its arguments, for example, if you have a function foo that takes 2 numbers
      function foo(nr1, nr2) {
      return nr1 + nr2
      }
      and you do
      let boundFoo = foo.bind(null, 4, 5)
      boundFoo is now a function with a this value of null, which adds 4 and 5
      you can now call boundFoo without arguments
      boundFoo()
      and it will return 9.
      Matias is simply returning the new function directly.
      Hope that makes sense!

    • @benjaminmosnier
      @benjaminmosnier 7 ปีที่แล้ว +1

      This makes a lot of sense, really - And the "pre installed" or "pre filled" automation makes a lot more easier to undestand why the dependencies have to be the first of the arguments

    • @benjaminmosnier
      @benjaminmosnier 7 ปีที่แล้ว +4

      very crystal clear explanation, thank you - I have to say I am happy to have asked this, because now i will be able to reuse this in my work, like, this morning after a fresh coffee !

  • @navroze92
    @navroze92 6 ปีที่แล้ว

    Thank you for the amazing video MPJ. I have my concepts related to testing much clearer. Also I have a small doubt. I am not sure how many of the people out there will be well versed with inversion of control and dependency injection. They might think why the hell am I passing these functions which I can use them by requiring them through modules. Won't this be a little ambiguous to someone who reads the code. Is there a way to make this more elegant?

    • @funfunfunction
      @funfunfunction  6 ปีที่แล้ว

      In the end, you need to learn what dependency injection is and what the benefits are. There’s no shortcut around that. There are magic tools that do dependency injection in more terse ways, but they make it even harder to understand the concept for someone new.

  • @vincentzhang7211
    @vincentzhang7211 7 ปีที่แล้ว

    Thank you for the fantastic video. And I am pretty impressed by your passion, haha!

  •  7 ปีที่แล้ว

    What if createStoreDocument is used multiple times across different files, would still inject create the bound-function or just create a singleton file that injects the dependencies and returns the same bound-function each time?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      createStoreDocument would only used at the root level.

  • @Aramizyera23
    @Aramizyera23 5 ปีที่แล้ว

    So DI is parametrization by interfaces and IoC is partial application?

  • @MarcelRobitaille
    @MarcelRobitaille 7 ปีที่แล้ว +2

    How do you learn the terms? I have been doing that kind of stuff for a while but never knew what it was called.

    • @daggawagga
      @daggawagga 7 ปีที่แล้ว +3

      If you look up "design patterns" you will stumble upon this and many other related terms that are solutions for relatively common problems in programming / design

    • @DanFletcher90
      @DanFletcher90 7 ปีที่แล้ว +4

      Look up SOLID principles - that'll get you pointed in the right direction :)

    • @MarcelRobitaille
      @MarcelRobitaille 7 ปีที่แล้ว +3

      Cool. Thanks guys.

    • @waveFunction25
      @waveFunction25 7 ปีที่แล้ว +4

      I first heard of it reading the documentation of Laravel. Reading docs will usually get you introduced to technical terms. Or you can read books on patterns.

    • @DanFletcher90
      @DanFletcher90 7 ปีที่แล้ว +2

      Gustavo That's actually how I first learned these terms too - cheers!

  • @OfferoC
    @OfferoC 7 ปีที่แล้ว

    Thank you. Great explanation.

  • @Anemoleiro
    @Anemoleiro 7 ปีที่แล้ว

    Is it good to use unit test in small(not enterprise) js applications? Seems like it is really time consuming

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      It takes a little bit of time to write unit tests, yes, but it will eat a lot more time if you DON'T have them. In a very, very small app that you anticipate to only live for a couple of months, then maybe unit tests theoretically will be a bad investment, but I find that they start paying off after just a couple of thousand lines of code and a couple of months development. Even in an app that young, there are literally many hundreds of things that can go wrong and it's just not feasible to maintain quality even in a small app without unit testing.

  • @caferrari
    @caferrari 7 ปีที่แล้ว

    MPJ, do u use any kind of IoC container for node.js?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +3

      +Carlos Ferrari no. I used to when I was younger, but over the years I've realized that if a task is simple to solve with simple means, you should not add a tool to your repertoire for it. In the same vein, I have this fancy onion cutter thing, but lately I bought a really good chefs knife, and got into learning how to properly chop vegetables, and I now find myself getting better results with the knife, without the dishes and storage and extra meez involved with the onion cutter. Less is more.

    • @caferrari
      @caferrari 7 ปีที่แล้ว

      Thanks, that's exactly the feeling that I had when I was looking around for alternatives. A lot of unecessary and overcomplicated solutions.

  • @TanGuven
    @TanGuven 7 ปีที่แล้ว

    Wow I can build every dependency like a lego and I can swap any part anytime. That's what I understand :)..

  • @krzysztofkabat9166
    @krzysztofkabat9166 7 ปีที่แล้ว

    what are your thoughts on automatic dependency injections like those in angular 1.x?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      I think it's bullshit, frankly. I'm not a fan of making libraries and frameworks for things that can very easily be done with a few lines of code.

  • @flakaal
    @flakaal 6 ปีที่แล้ว

    Hello Mpj nice to see you wear Albanian flag

  • @jedrzejsadowski6810
    @jedrzejsadowski6810 7 ปีที่แล้ว

    Great vids!
    Personally I usually use a mix of this approach (when the flexibility gain is what I want) and using Rewire (in other scenarios), or more precisely its babel plugin github.com/speedskater/babel-plugin-rewire.
    In fact, if you think of modules as functions having some default input (imports) and output (exports), than rewire lets you change the inputs to the module.
    Using IoC for this example looks like a bit of an overkill for me. You have to change quite a bit of your application code just to make it testable, where db apis are usually specific & shouldn't be the concern of main.js.

  • @przemysawlib4309
    @przemysawlib4309 7 ปีที่แล้ว

    Partial application to the rescue ;)

  • @RealHeiggins
    @RealHeiggins 7 ปีที่แล้ว

    That was really good. Thanks!

  • @PapaLazarou19
    @PapaLazarou19 7 ปีที่แล้ว

    seems like you just shifted the dependencies you might have had to inject anyway into the storeDocument function into the factory class/func first. I guess you can't really help having to have an initial place where all dependencies are instantiated and injected. I suppose it's a balance between containers of dependencies and just enumerating all dependencies in a flat fashion - I guess the decision of where to draw the line is part of describing meaning/responsibility to the funcs/classes (by defining what the required parameters are).

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      In one way yes, but we're not just shifting where we do the injection, we're also centralising the injection. Injection might need to happen in a ton of places if we don't do this.

    • @PapaLazarou19
      @PapaLazarou19 7 ปีที่แล้ว

      funfunfunction sure. It makes sense to put some generalities around the necessary injections if you can. The motivations for this should be encapsulating logic in the program I guess though right? while keeping in mind being able to test the code at the same time. Rather than wrap some parameters up just for making testing easier.. unless that's its specific purpose. .. I'm just thinking out loud... It's interesting how the mechanics of the language shape how we reason about what's being made sometimes.

    • @jtreher
      @jtreher 7 ปีที่แล้ว

      At some point you would want to build a container for all the things and just use the container. This is just a demo of the concept of IoC. There are a million libraries that implement the pattern and provide you with a container.

    • @PapaLazarou19
      @PapaLazarou19 7 ปีที่แล้ว

      Justin Treher yeah I know about containers. You don't pass a single ref of your container to all or any your things needing dependencies. I don't think you get what I meant

  • @edvinsantonovs
    @edvinsantonovs 7 ปีที่แล้ว +1

    Great stuff, thanks!

  • @kimjongun5073
    @kimjongun5073 4 ปีที่แล้ว

    .bind Looks like partial application in functional programming!

  • @andyfangaf
    @andyfangaf 7 ปีที่แล้ว

    What recording software do you use?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      +Andy Fang see the behind the scenes episode

  • @AndrewSmithDev
    @AndrewSmithDev 7 ปีที่แล้ว

    Good video professor Johansson

  • @ivofx2134
    @ivofx2134 6 ปีที่แล้ว

    Very helpful, thank you

  • @DiscoverYourDestinations
    @DiscoverYourDestinations 5 ปีที่แล้ว

    Good t-shirt man :P Albanian guys are the best!

  • @Voltra_
    @Voltra_ 7 ปีที่แล้ว +1

    We could also curry the function?

  • @Iextrimator
    @Iextrimator 7 ปีที่แล้ว +2

    Why "let storeDocument" and not "const storeDocument", am I missing something?

    • @Iextrimator
      @Iextrimator 7 ปีที่แล้ว +1

      I mean, since you insist on using const where you can

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +2

      No particular reason, I just felt like it at the moment. :)

  • @maagiapall
    @maagiapall 7 ปีที่แล้ว

    What I don't understand is how this is beneficial for testing in a world where we have things like `jest.mock` to mock dependencies to do whatever we want.
    To me, this looks like we are creating abstractions that make the code less logical and readable, only for the benefit of making testing easier. If testing shows that some of the business logic should be changed, I'm all for that, and if you're doing TDD, then it makes sense that writing tests first influences the business logic, but I don't understand why we should be messing with our code for the express purpose of helping out the tests, to the detriment of the underlying code. I think tests influencing business logic should ultimately benefit the business logic, even without the tests.
    And DI doesn't seem to do that here. It seems like a solution to a problem that today has better solutions, that don't make the code more fragile, create unneeded indirection, and boilerplate.

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      +Magix excellent question!
      you can absolutely argue that mocking on a module level as an alternative approach to this. The purpose of this video is to explain the technique, not argue that it's the be-all-end all of handling testing of dependencies.
      Jest.mock is a perfectly valid alternative to this. However, there is no magic bullet - it does have its drawbacks. What IoC does have going for it over stuff like jest.mock is that it is decidedly unmagical and can be done without fancy tooling. jest.mock does quite a bit of magic, so you've introduced a very sophisticated tool into your chain, that also ties you to jest, and that developers have to learn and understand. In contrast, I have not used a single third-party tool to achieve the stuff we done in these videos. IoC also has the benefit of being a pattern that is well-understood by the industry, and has a great chance of the developer being familiar with if they have a few years of development experience, even if they are new to JS.
      Also, you are effectively using the require system for dependency injection, which is not quite as flexible as IoC which allows you to do more things before with it injecting the dependency.

    • @maagiapall
      @maagiapall 7 ปีที่แล้ว

      Good points. So given that both have their pros and cons, which would you choose when starting a project? Or if it's on a case by case basis, how do you decide?
      I would still go with Jest in any situation if it was up to me, given that most of my projects already have a non trivial tooling setup, and Jest is rather well known + the API for mocking a module is very straightforward. It's definitely really magical, but in a way that I don't really ever have to concern myself with. I can just trust that the magic is well tested and implemented by the folks behind the library, and I probably won't have a reason to have to dig into the implementation.
      Sidenote - as an explanation of the technique, you did a fantastic job =P

  • @mxschmitt_
    @mxschmitt_ 7 ปีที่แล้ว

    Promises are awesome

  • @electron0zero
    @electron0zero 7 ปีที่แล้ว

    Thanks mpj

  • @shihang7422166
    @shihang7422166 7 ปีที่แล้ว

    It's actually partial function evaluation

  • @slawekzalupka1109
    @slawekzalupka1109 7 ปีที่แล้ว

    Thank you!

  • @snira5475
    @snira5475 7 ปีที่แล้ว +1

    This storeDocuments is already doing more than it say it does which is violation of single responsibility principle.
    should be separate into two functions, one that check if user can store document and one that actually store the document
    great example though

  • @BalticWind
    @BalticWind 6 ปีที่แล้ว

    Thanks!

  • @jahilkhalfe
    @jahilkhalfe 7 ปีที่แล้ว

    Do fish drink water? How and where do they sleep?

  • @wizardslies
    @wizardslies 7 ปีที่แล้ว

    What was the null argument for?

    • @bohemian_demon
      @bohemian_demon 6 ปีที่แล้ว

      If you're referring to the null in storeDocument.bind(null,etc), in the video he explains that we don't care about binding storeDocument to an existing 'this' and therefor a null can be passed in its place. For more detail I recommend checking out MPJ's video on bind.

  • @rickmedina4082
    @rickmedina4082 7 ปีที่แล้ว

    why not use partial application instead of bind?

    • @jtreher
      @jtreher 7 ปีที่แล้ว

      Because he would
      have to discuss the implementation of his partial application function. Everyone knows bind.

    • @rickmedina4082
      @rickmedina4082 7 ปีที่แล้ว

      Not everyone (see pinned question). Also, he has explained currying in another video (just link to it).

  • @mikeeam
    @mikeeam 7 ปีที่แล้ว

    Why not import the dependencies directly in the factory file?

    • @MaxStagsted
      @MaxStagsted 7 ปีที่แล้ว +1

      week links are better than hard links. If you want to change the dependencies later, you dont want to have to update the factory file.

  • @RutgerWillems
    @RutgerWillems 7 ปีที่แล้ว

    In the comment section of the Dependency Injection basics video I was asking about this and someone recommended to export one function '_fun1' for testing and one 'fun1' for further use in your application.
    I'm currently doing it the following way, any comments about this? Better, worse or personal preference?
    ---
    export function _getFromTVDB (fetch, getAuthKey, path) {
    return new Promise(function (resolve, reject) {
    getAuthKey().then(key => {
    fetch(`api.thetvdb.com/${path}`, {
    method: 'GET',
    headers: {
    'Authorization': 'Bearer ' + key,
    'Accept': 'application/json',
    'Content-Type': 'application/json'
    }
    })
    .then(r => r.json())
    .then(r => resolve(r.data))
    .catch(e => reject(Error(e)));
    });
    });
    };
    export function getFromTVDB (path) {
    return _getFromTVDB(fetch, getAuthKey, path);
    };
    ---

  • @shapanization
    @shapanization 7 ปีที่แล้ว

    @funfunfunction Great Stuff! Would it be possible to make a video about where/how I can get ideas for projects (like the facebook bot and making an editor) to get my hands dirty with coding.

  • @micheldiz
    @micheldiz 7 ปีที่แล้ว

    Can you talk about the "fetch" features?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      +Michel Conrado I'm trying to stay away from content that is only interesting to JavaScript programmers. You can find excellent material on he Fetch API by googling it.

    • @micheldiz
      @micheldiz 7 ปีที่แล้ว

      I'm not a javascript programmer... i'm studying as well. That's why I'm here at your channel...

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      Hmm, it's tricky. I don't want this to turn into a JavaScript channel that is uninteresting to someone that doesn't particularly want to learn JavaScript.

    • @micheldiz
      @micheldiz 7 ปีที่แล้ว +1

      funfunfunction wat? My first impression was that this channel is about javascript oO
      I'm just interested about how to manipulate correctly data coming from an API using fetch... (with simple examples) You talk about other complicated things. And there's no good channel doing this (Dissecting fetch) Didactically. So what ever. Thanks. I appreciate your attention

  • @audidood
    @audidood 7 ปีที่แล้ว +4

    squigglywings. hehe

  • @ilyakogan
    @ilyakogan 7 ปีที่แล้ว

    I've been using and helping people learn inversion of control for 8 years and I still have no idea what its name means.

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      Yeah, we would really have picked a more pedagogical one.

    • @fraklopez9521
      @fraklopez9521 7 ปีที่แล้ว +1

      I might have this wrong, but I believe it's because normally, the calling function exerts control over the called function.
      That is, ash() would say, pikachu() I call you, here are the things you need. Go forth and battle on!
      With IoC, the ash() says, pikachu() I call you and pikachu says, ok great, I need these things - goes and gets them then goes to battle on!
      In the first example, the ash function has to know what pikachu will need and provide it. ash() has to control pikachu.
      In the second, ash() doesn't need any knowledge and relies on pikachu to know what it's doing, thereby relinquishing control to pikachu.
      Sorry for the analogy, I think MPJ's shirt got to me. ;)

  • @Todiros
    @Todiros 7 ปีที่แล้ว

    Hi, my name is Main Jayass.

  • @AmanGupta_Dev
    @AmanGupta_Dev 7 ปีที่แล้ว

    at 4:09 way too funny :D :D

  • @AB-ut3ce
    @AB-ut3ce 7 ปีที่แล้ว

    Isn't that just a partial?

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว

      +Adam Baszak partial is the tool we use to achieve the structure, but we could have used something else, such as a class, to do it.

    • @AB-ut3ce
      @AB-ut3ce 7 ปีที่แล้ว

      Yeah, I appreciate that you laid down an idea in a structured way. Just needed to leave a snarky comment.

  • @shihang7422166
    @shihang7422166 7 ปีที่แล้ว

    It's not inversion of control, it's encapture

  • @bugkilla84
    @bugkilla84 7 ปีที่แล้ว

    So many extra lines! It's frustrating , that writing good code is so cumbersome. We all want to get things done quickly. Why do we have to always choose between quality and speed?!

    • @jeroldhaas915
      @jeroldhaas915 7 ปีที่แล้ว

      In this case, the extra LoC increase refactoring / maintenance ease. You're reducing technical debt by adding those lines of code. Once software reaches a maintenance cycle it's much easier to see where IoC and DI really shine. HTH
      _Edit - I'd forgotten to mention: this form of decoupling is also very useful when dealing with test frameworks._

    • @bugkilla84
      @bugkilla84 7 ปีที่แล้ว

      Jerold Haas It's not that I'm not getting the bennefit. I totally do. But I just wished writing quality code was achievable with the same (or less) amount of lines as the not-so-maintainable version. Why is it that languages tend to make it harder to achieve quality? Shouldn't IoC be embedded in a language for example.

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      +ACD Ba number of lines of code is really not relevant to speed of development. That is a complete illusion. It has no more to do with speed of development than the color of the car is related to its performance.

    • @jeroldhaas915
      @jeroldhaas915 7 ปีที่แล้ว

      I'm in partial agreement with that statement. I do have admit there is a certain amount of debt incurred when LoC gets obscene, or when comparing languages with more boilerplate code. In the first case it's likely symptomatic of some other coding anti-pattern happening. The latter can be resolved with tooling such as snippets or refactoring tools.
      That said, if you were to compare the original code to the end of video code (subtracting white space), there's actually not much added.

    • @bugkilla84
      @bugkilla84 7 ปีที่แล้ว

      funfunfunction What is it then? When faced with time pressure even experienced developers tend to write shitty code. Why are we unable to write good code in the same amount of time as bad code?

  • @MissMarsi
    @MissMarsi 6 ปีที่แล้ว

    Is that the Albanian flag on your shirt?

  • @tomasluken
    @tomasluken 7 ปีที่แล้ว

    today i have returned my first poop ever

    • @dtipson
      @dtipson 7 ปีที่แล้ว

      tomas. thanks'

  • @wojtekobsysa
    @wojtekobsysa 7 ปีที่แล้ว

    I am just reading through You Don't Know JS book github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch2.md
    And there's also definition od inversion of control regarding callbacks. Could you elaborate on how this relates to the case presented here?

  • @noorkhorasi
    @noorkhorasi 5 ปีที่แล้ว

    Find the callback hell ;)

  • @panchosanza9995
    @panchosanza9995 7 ปีที่แล้ว

    oh yea its just a black box i can command with magic. rock on.
    (inhale, smile, and let sub spiritual osmosis education seep into your brain)

  • @Shaolinguru1
    @Shaolinguru1 7 ปีที่แล้ว

    You albanian?

    • @DavidWhitman1990
      @DavidWhitman1990 7 ปีที่แล้ว

      Shaolinguru1 He is Swedish.

    • @Shaolinguru1
      @Shaolinguru1 7 ปีที่แล้ว

      David Whitman I know that he lives in Sweden but he can still be ethnic Albanian or have roots from there

    • @Shaolinguru1
      @Shaolinguru1 7 ปีที่แล้ว

      thats albanian coat of arms on his T-shirt just to clarify

    • @funfunfunction
      @funfunfunction  7 ปีที่แล้ว +1

      I bought the shirt in Brazil. Albanian is not a bad guess, there lives a lot of Albanians in Sweden, but I'm not one of them.