Dependency Injection | Prime Reacts

แชร์
ฝัง
  • เผยแพร่เมื่อ 10 ส.ค. 2023
  • Recorded live on twitch, GET IN
    / theprimeagen
    Link to reviewed video: • Dependency Injection, ...
    Posted by: CodeAesthetic | / @codeaesthetic
    MY MAIN YT CHANNEL: Has well edited engineering videos
    / theprimeagen
    Discord
    / discord
    Have something for me to read or react to?: / theprimeagenreact
    Hey I am sponsored by Turso, an edge database. I think they are pretty neet. Give them a try for free and if you want you can get a decent amount off (the free tier is the best (better than planetscale or any other))
    turso.tech/deeznuts
  • วิทยาศาสตร์และเทคโนโลยี

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

  • @zored1337
    @zored1337 11 หลายเดือนก่อน +468

    Ohh fLiP dO yOur jOb

    • @TakenTooSeriously
      @TakenTooSeriously 11 หลายเดือนก่อน +23

      Scuffed audio

    • @sikaydalapixia5924
      @sikaydalapixia5924 11 หลายเดือนก่อน +2

      mean

    • @WedgeTalon
      @WedgeTalon 11 หลายเดือนก่อน +37

      He probably could've EQd it out, but I bet he would make some lame excuse like editing 20 videos. Pfffft

    • @flipmediaprod
      @flipmediaprod 11 หลายเดือนก่อน +94

      i hate you guys

    • @josevargas686
      @josevargas686 11 หลายเดือนก่อน +12

      ​@@flipmediaprodI for one, thank you, the videos wouldn't be as fun otherwise

  • @ivankudinov4153
    @ivankudinov4153 11 หลายเดือนก่อน +379

    We need to praise code aesthetics more: amazing production quality, deep insights, real-world advanced examples, 0 bs. All been made single handedly by an independent small youtuber. Such a gem

    • @gagagero
      @gagagero 8 หลายเดือนก่อน +17

      "Don't write comments". It's all hipster nonsense. That is unusable in the real world.

    • @SlavaEremenko
      @SlavaEremenko 8 หลายเดือนก่อน +7

      It’s all hype no substance. Just read one chapter of POODR on dependency injection and you are good to go

    • @josefpharma4714
      @josefpharma4714 6 หลายเดือนก่อน +1

      @@gagagero
      1. if you don't share an opinion, asking the other to stop "writing comments" is quite ignorant.
      2. Considering dependency injection unusable in for real world is even more ignorant. 🙂
      Or did I miss your point?

    • @joestevenson5568
      @joestevenson5568 6 หลายเดือนก่อน +10

      ​@@josefpharma4714He's talking about code aesthetics saying code shouldn't have comments, not telling people to stop commenting...

    • @abuDA-bt6ei
      @abuDA-bt6ei 15 วันที่ผ่านมา

      @@SlavaEremenko is it good if you don’t use ruby?

  • @KennethBoneth
    @KennethBoneth 11 หลายเดือนก่อน +34

    OOPERS when they discover function parameters, "THIS IS THE BEST PATTERN EVER!"

  • @asdqwe4427
    @asdqwe4427 11 หลายเดือนก่อน +94

    I have three rules for DRY
    1: if the code has reason to change independently, just copy paste instead.
    2: if I notice that a function has become aware of where it is being used, I know that I messed up. Signs of this is when parameters keep getting added. Usually those parameters contain words like skip or include.
    3: don’t bother reusing trivial stuff
    Usually rule 2 is a result of not following rule 1.

    • @needsloomis7164
      @needsloomis7164 11 หลายเดือนก่อน +24

      #2 is a great. I call them slutty functions (they're too desperate to make everyone happy).
      I'd also add that base functions should mostly be abstract. If you find yourself writing virtual functions to avoid typing more words, you should either copy/paste or make a component. When I have trouble figuring out what a class is even doing (without digging through its parents), I know I fucked up.

    • @DryBones111
      @DryBones111 11 หลายเดือนก่อน +12

      #2 is a symptom of mistaking syntactic repetition for semantic repetition. The former should not be refactored.

    • @Turalcar
      @Turalcar 10 หลายเดือนก่อน

      @@DryBones111 likely, with a strategy

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

      @@needsloomis7164 HAHAHAHAHAHAHAHAHAHAHAHHAAHHAA

    • @azzyfreeman
      @azzyfreeman 9 หลายเดือนก่อน +3

      Yep, some ppl think I am being lazy, when I tell then to just copy the component and change it a bit. It is difficult to explain that those are different use cases and I am trading some duplication for less buggy code

  • @throwaway3227
    @throwaway3227 11 หลายเดือนก่อน +227

    In Haskell, dependency injection is the norm (as your Monads are implicitly given to monadic functions when called, and they can easily be replaced with compatible Monads). Since it's such an integral part of the language, having DI everywhere is no longer an issue, since the typing system is so beautiful.
    I program in Haskell, by the way.

    • @HrHaakon
      @HrHaakon 11 หลายเดือนก่อน +43

      Like a vegan crossfitter... :p

    • @NNOTM
      @NNOTM 11 หลายเดือนก่อน +23

      I think it's worth pointing out that even though you say it's an integral part of the language, it's not like the designers of Haskell set out to design a language that has built-in support for dependency injection. It's more that the features you have available in Haskell lend themselves well to implementing dependency injection in a very idiomatic way.

    • @jonescity
      @jonescity 11 หลายเดือนก่อน +31

      Do you use Arch Linux too?

    • @RegularTetragon
      @RegularTetragon 11 หลายเดือนก่อน

      Then you've got monad transformers which let you dependency inject your dependency injections

    • @Mglunafh
      @Mglunafh 11 หลายเดือนก่อน +2

      Thank you for your service!

  • @EmilyGamerGirl
    @EmilyGamerGirl 9 หลายเดือนก่อน +23

    So, for the testing, they are testing the actual uploading code with the fake encryption- so if that test fails, you know the uploading has an error, rather than just knowing that the error is in either uploading or encryption or the key. Then for the encryption test, using a fixed test key makes total sense- and then integration testing by uploading an encrypted file, but, with a fixed test key still. This makes total sense as a great way to test stuff.

    • @Kenionatus
      @Kenionatus 5 หลายเดือนก่อน +5

      And he might have not shown all the upload tests that use mock encryption and mock storage. If you have a good mockup of the storage service (maybe Amazon provides one?), you can test error handling etc in isolation. Showing like 15 test cases wouldn't have fit in the video tho.

  • @deamorta6117
    @deamorta6117 11 หลายเดือนก่อน +19

    Brother, you're like my go to for learning the how-tos of programming. Because of your teaching and memes i got a new job with higher salary. thanks Prime.

  • @timwhite1783
    @timwhite1783 11 หลายเดือนก่อน +9

    You know you've gone too far with Dependency Injection when you're struggling to find your concrete implementations.

  • @paklenizmaj
    @paklenizmaj 11 หลายเดือนก่อน +6

    I agree, don't repeat yourself a lot (3-5 times is fine) and code first so that things work, then you can clean and optimize. once you start cleaning and tuning, you can write tests to be sure and stable, before that you don't need the tests too much.
    Greate video and great comments ;)

  • @timseguine2
    @timseguine2 8 หลายเดือนก่อน +62

    Strategy Pattern is one of the things that always seemed so obvious to me that I question the utility of giving it a name.

    • @whaisonw2865
      @whaisonw2865 7 หลายเดือนก่อน

      Yes! I was just like: This shit has a name?? But as he said it just comes with experience

    • @pah967
      @pah967 6 หลายเดือนก่อน +1

      try other patterns, get out of your comfort zone!

    • @timseguine2
      @timseguine2 6 หลายเดือนก่อน +7

      @@pah967 That's a weird comment that assumes a lot I didn't say.
      "Strategy pattern is an obvious pattern" does not equal "Strategy pattern is literally the only pattern I ever use."
      Turning your comment back around: maybe don't give unsolicited advice especially when it is also not even relevant advice.

    • @pah967
      @pah967 6 หลายเดือนก่อน

      @@timseguine2 well, based on your reply to my half-assed attempt at promoting exploration, I can only say... well aren't you a belligerent self-important c*nt?

    • @RainbowVision
      @RainbowVision 5 หลายเดือนก่อน +2

      ​@@pah967in addition to the above, if you're only hitting nails, then all you need is a hammer 😉 using some arbitrary design pattern for the sake of it is a quick way to ruin your code

  • @bartkl
    @bartkl 11 หลายเดือนก่อน +108

    DRY is often misunderstood. The idea isn't to never repeat yourself, but to have all _information_ have a single source of truth. That is, you don't want to have to change some fact in several places since that will definitely come to haunt you.
    In the Pragmatic Programmers book they actually explicitly give an example of deliberate code repetition in case it represents different concepts/information.
    Just FYI :)

    • @uglypie182
      @uglypie182 11 หลายเดือนก่อน +5

      So true! This is also why WET isn't really any better

    • @needsloomis7164
      @needsloomis7164 11 หลายเดือนก่อน +5

      I think that's conceptually true, but in practice the "haunting" is often just having to change the same line in 4 places when it breaks during a refactor, which is often faaaaaar better than the deep rooted architectural cancer that comes with the dependency and inheritance spaghetti people use to avoid writing some simple procedure a few times.
      I agree that important dogmatic information is def something that should come from one source.

    • @bartkl
      @bartkl 11 หลายเดือนก่อน +4

      @@needsloomis7164 Yes I agree people shouldn't go nuts that way. Apply pragmatism at all times I guess.

    • @jongeduard
      @jongeduard 10 หลายเดือนก่อน +1

      My personal very simple explanation is that I should not do the work for the computer, the work at which it's even excellent.
      Repetition should be programmed where possible, not directly written. And even in cases where I am in a situation where I actually need tons of duplicate code due to technical limitations, then it's time to look for ways to generate that code (metaprogramming, macros).

    • @bartkl
      @bartkl 10 หลายเดือนก่อน +6

      @@jongeduard To emphasize the point I was trying to make: sometimes two segments of code might be identical, but they represent completely unrelated things, a consequence of which is that if one changes, the other shouldn't. Had you abstracted this repetition away, your code would've been harder to change for the wrong reasons.
      Not disagreeing btw, just wasn't sure if I made my point clearly enough.

  • @unimportantperson5766
    @unimportantperson5766 11 หลายเดือนก่อน +204

    Dependency Injection is like one of the best things invented ever. When you want to share a bunch of code between other bunch of code, and you realize that Inheritance is inappropriate, then DI is the way to go.

    • @Robert-zc8hr
      @Robert-zc8hr 11 หลายเดือนก่อน +47

      It's just configurable composition though.

    • @unimportantperson5766
      @unimportantperson5766 11 หลายเดือนก่อน

      @@Robert-zc8hrLet me clarify what I meant. I recently had a conversation with colleague, who wanted to wrap a bunch of unrelatex stuff (like Logger) into one BaseClass, and then just inherit from it in Commands and Queries (CQRS pattern. We are using .Net Core), instead of injecting as dependency. And I just stopped her from doing that, because it doesn't make sense from Liskov Substitution principle perspective. The child classes are responsible for completely different things than BaseClass. So we decided to go with simple DI option.

    • @deadvirgin428
      @deadvirgin428 11 หลายเดือนก่อน +47

      Inheritance is never appropriate.

    • @kellyrankin8844
      @kellyrankin8844 11 หลายเดือนก่อน

      ​@@deadvirgin428amen

    • @notuxnobux
      @notuxnobux 11 หลายเดือนก่อน +15

      I have trauma from java spring dependency injection with xml. You can easily do the same thing with configurable composition and there is no magic behind the scene, it's much easier to read and it works much better with IDEs.

  • @aipt32
    @aipt32 11 หลายเดือนก่อน +1

    I saw the original video and since then i refreshed your channel every few hours waiting for a reaction.❤

  • @chndrl5649
    @chndrl5649 11 หลายเดือนก่อน

    Been waiting for this one! Love the take good stuff!!!!

  • @heinzerbrew
    @heinzerbrew 10 หลายเดือนก่อน +1

    New to the channel. This guy is so way over my head, it depresses me. There is just so much to know and understand.

  • @andrewnleon
    @andrewnleon 7 หลายเดือนก่อน +1

    You make it fun to learn the science behind code thanks man!

  • @midnighthoosk
    @midnighthoosk 11 หลายเดือนก่อน +28

    Mocking allows you to test the happy and the bad paths... So you can tell your mocked dependencies to return a bad result or a service outage or something from your result and handle that in the tests that way you know your code is going to handle everything properly...

    • @ThePrimeTimeagen
      @ThePrimeTimeagen  11 หลายเดือนก่อน +15

      sort of
      this works with services you run and control, it gets a bit more different when you are mocking a service you don't know (everything) or control

    • @ikincidev
      @ikincidev 11 หลายเดือนก่อน

      ​​@@ThePrimeTimeagen yes, I think this works well for our services and well documented third-party services

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 11 หลายเดือนก่อน +25

      @@ThePrimeTimeagen But if you don't understand the service you're using completely, then you probably also don't want to handle all of its errors. You probably just want to catch ThisService::SaveFailedException, and in that case, a mock impl that just returns a generic "shit went bad", would be equivalent.

    • @CraigLuna
      @CraigLuna 11 หลายเดือนก่อน

      It comes down to costs often. It is harder for some teams to get the budget so have to mock/short circuit/substitute the costly resources so they can validate the rest of the pipeline. We depend on SLA to provide the certainty of those resources and then being validated during integration testing.
      Ideally you would never want to mock it and your team would have it budgeted.
      @@ThePrimeTimeagen

    • @streettrialsandstuff
      @streettrialsandstuff 9 หลายเดือนก่อน +3

      ​@@ThePrimeTimeagenthat's the thing. With unit testing you are testing a unit. You don't want a broken AWS or a broken image scaler to break your uploader test. These should be tested separately, so when something breaks it doesn't affect testing of your other components which are not broken.

  • @GingerGames
    @GingerGames 11 หลายเดือนก่อน +63

    This is one of the reasons why I hate OOP (not necessarily objects): all of the stupid names for simple things. "Dependency Injection" is just passing objects to procedures as a value. WHY DOES IT NEED A SILLY NAME LIKE THAT?!

    • @ekfliu
      @ekfliu 11 หลายเดือนก่อน +7

      Its just a fancy name for composition where object is determine at runtime either by configuration or automatically. hell I used spring since 1.x, never heard the term until 3.x

    • @dealloc
      @dealloc 11 หลายเดือนก่อน +13

      DI is not unique to OOP and has nothing to do with it. It's a general term that generally describes the concept.

    • @GingerGames
      @GingerGames 11 หลายเดือนก่อน +22

      ​@@deallocThe only people who use the term are OOP people. Everyone else doesn't even bother naming it because it's such a trivial concept, and only seems "great" if you have been doing insane OOP things.

    • @thewhitefalcon8539
      @thewhitefalcon8539 11 หลายเดือนก่อน +5

      It's a pattern. It's not every time you pass something to something, it's a specific type of passing something to something. You're asking why we don't just call singletons static variables and the answer is that not all static variables are singletons.

    • @GingerGames
      @GingerGames 11 หลายเดือนก่อน +8

      ​@@thewhitefalcon8539I am not asking about calling singletons. I am literally saying that "dependency injection" is a silly name, not that is a bad idea.

  • @ArnorHjaltason
    @ArnorHjaltason 11 หลายเดือนก่อน +4

    Without being a big fan of using mocks for integration tests they make a lot of sense in the case that you do black integration testing and white unit testing.
    That way you can make sure that the units conform to the interface and the mock getting a lot of depth from those tests, then the integration tests can be very shallow and be very wide with minimal effort.
    This allows for great coverage at the cost of minimal brain power, you can then argue if that is worth or not.

  • @BloodEyePact
    @BloodEyePact 11 หลายเดือนก่อน +12

    The testing issue raised around 23:50 is something I run into a lot, especially with teams that are just starting out on their automated testing journeys. I have a simple rule: If that mock could conceivably be used in production (e.g. sqlite instead of postgres, a file directory instead of s3), then its a useful mock. If it would be worthless in production, its a worthless mock, and a worthless test, throw it away. For those, the only real way you can test them is to spin it up in docker compose or k3s and test it for real.

    • @joaomacedo673
      @joaomacedo673 10 หลายเดือนก่อน +1

      Unit tests that ensure that some service burried deep within a method is called with the parameters you expect are useful and important and they should use mocks because you are are testing the service call itself, not what happens after.
      I like to divide unit tests in 2 categories: testing pure functions or testing lateral effects. In the former you test expected outputs for given inputs. In the latter you test that a class/service/whatever (eg an api or storage) gets called like you expect it to. Both are important IMO. But of course to test the real deal you need integration tests and there your statement is of course valid.
      So perhaps I misunderstood something but I don't get the lashing on mocks/stubs

    • @BloodEyePact
      @BloodEyePact 10 หลายเดือนก่อน +2

      @@joaomacedo673 "Was this called or not" is not a terribly useful test. The common way to mock such a thing is to validate that the arguments passed match what is expected and to return a canned response. This seems useful when you first look at it, until you realize that you've encoded your assumption about how that remote service behaves into the test. Its one step above running the test, capturing the output, and then updating the test to assert the output is what you just copy pasted. It is not testing anything except that no exceptions were thrown/errors returned. The only useful test in such case is one in which a representative-enough replacement is used, such as sqlite for a real DB. If you cannot test the intermediate logic without having it try to call to an external service, that usually indicates soon-to-be catastrophic architectural issues.

    • @joaomacedo673
      @joaomacedo673 9 หลายเดือนก่อน +1

      ​@@BloodEyePact I'm talking about testing the service/database/wathever is called with the arguments it's supposed to be called. What that call returns and what happens after doesn't matter in the case I was talking about, as one is just concerned that under specific circumstances your method performs the call with the correct parameters to produce the intended side effect.
      In fact I don't see the point of replacing the actual implementation of the database or filesystem by some other that could be viable in production. It's either the real deal (integration testing) and there, yes, you test the whole system/subsystem end to the end, or pure mock to assert the side effect call is performed as it's supposed to (unit testing).

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

      ​@@joaomacedo673Testing that a service was called or a database was queried is not a useful test, unless the software in question is specifically about making that call/query, because that is an implementation detail, and tests should never test implementation, only behavior observable to the user (whether that user is someone behind a browser, another program calling a library method, etc). You replace the implementation so as to not depend on external services which is poison to test reproduciblity, and therefore, result validity. Testing that a call was made with parameters assumes you know the correct parameters/query/etc to make, which you don't, and encoding what you /assume/ the correct parameters/query/etc into the test invalidates it, because it only tests that it matches your assumptions, not that your assumptions are correct.

    • @NoOne-ev3jn
      @NoOne-ev3jn 9 หลายเดือนก่อน

      You test a scenario, that dependency in that scenario is just behaving normally, in another scenario we can make it fail.

  • @me-yf2tv
    @me-yf2tv 11 หลายเดือนก่อน

    thanks for the great, educational content Prime!

  • @merodach566
    @merodach566 2 หลายเดือนก่อน

    The moment you defined `as const` as the "pointer to a constant", I immediately thought about trying the exact same experiment you did with `let`. Glad you covered that 10 seconds later.

  • @on-hv9co
    @on-hv9co 11 หลายเดือนก่อน +3

    "...comes down to two patterns: [builder] and [strategy]" - parsing library maintainers catching strays

  • @JonathanTheZombie
    @JonathanTheZombie 11 หลายเดือนก่อน +13

    This is one of my favorite patterns for plug-in type systems. Turning DI into abstraction hell is a code smell.

    • @Daniel_Zhu_a6f
      @Daniel_Zhu_a6f 11 หลายเดือนก่อน +1

      there cannot be to much if your language supports it well. that's why some languages even have special DI syntax sugar.

  • @rdf274
    @rdf274 10 หลายเดือนก่อน +4

    Having had quite some dozens of juniors come and go, a good chunk of them try to think of the pattern before prototyping. Some of them have this mindset of "If I use a good pattern from the start, I won't need to rewrite anything". Then they come up with the most convoluted solutions to easy problems. That was before we had code review so thankfully things are way better now.
    I understand this line of thinking, and it makes sense on a logical level, but never on a pratical level.
    And yeah, I think 99% of the good readable and testable code are strategy patterns that spawned after a functional prototype.

    • @verb0ze
      @verb0ze 6 หลายเดือนก่อน

      I agree with this. Even seniors I encounter are often bent on using design patterns everywhere. I tend to favor using patterns when they become apparent in what I'm doing as opposed to try to shoe horn some desired behavior into a pattern. Only exception to that is when I'm thinking architectural patterns when standing up or integrating with a service

  • @WolfieDad67
    @WolfieDad67 6 หลายเดือนก่อน

    I learned a lot watching the video you're discussing, mostly things I didn't know how to do.
    But "how" it's done is to me, nice and clean.
    I believe I got to the video from a video talking about using composition rather than inheritance.
    So, both the "favor composition" and "use DI" were to me 👍👍.
    I appreciate your comments as well Prime.
    Thanks to all.
    Will investigate the strategy, builder, and factory patterns much more now.

  • @stephenmcconnell7868
    @stephenmcconnell7868 10 หลายเดือนก่อน +2

    My last BIG project was one based upon a DI framework (in Java). It was great. However, there were times developers created some spaghetti apps where they created DI apps that data could get lost in. I think they didn’t design or think out their app well. While “not my code”, I would often get called at midnight to fix it. The code from our group based upon this framework had very few problems (most were traced to 3rd party data providers). We would work as a group to talk through data paths in our app. Worked well.

  • @simonrazer8303
    @simonrazer8303 10 หลายเดือนก่อน +2

    some luv to the editor, 20vids a day is insane!!

  • @yasscat5484
    @yasscat5484 11 หลายเดือนก่อน +62

    the only bad thing about dependency injection is that it breaks my "Go to Definition" as IDEs can't figure out which implementation you want to jump into so they take you to the interface .. pain

    • @kriscavitt3479
      @kriscavitt3479 11 หลายเดือนก่อน +16

      If you’re in Visual studio you can ctrl + F12 on the name and it will take you to the implementation.

    • @juxuanu
      @juxuanu 11 หลายเดือนก่อน +14

      On Jetbrains IDEs this is not an issue.

    • @tsalVlog
      @tsalVlog 11 หลายเดือนก่อน +4

      ​@@juxuanu it actually is, if you just use hotkeys and don't know there's a different one to get the implementation. if your current IDE can't figure out implementation from interface, it's time to upgrade to an IDE made in the last 2 decades. Or learn the hotkey.

    • @Ivcota
      @Ivcota 11 หลายเดือนก่อน +5

      ​@@tsalVlog I'm pretty sure most LSPs can list implementations if I'm not mistaken?

    • @GonziHere
      @GonziHere 11 หลายเดือนก่อน +1

      That's my biggest gripe with it. These graphs show you some data flow, which is nice and well, but actually seeing it is borderline impossible without a debugger. I don't mind that it can be complex (it has to be), but it's even worse to navigate than inheritance...
      And the simple thing is, that you "shouldn't" care about how the storage works, but you absolutely have to care when you deal with some obscure issue, or must extend it, etc.

  • @RogerValor
    @RogerValor 11 หลายเดือนก่อน +3

    In python, I usually have a default implementation of e.g. a Repo, that does exactly what it should do, and inject it. So the usual work of DI based usecases for clean arch become self-sustainable, and only while testing, I replace the dependency. I am not sure, why everyone shys away from happy path defaults. It makes it a lot easier to deal with, than having endless debates whether we should dependency inject this or that here or there, which is usually won by the guy who wants everything explicit, with ten interfaces, and quits the job right after everything has been refactored to this overexplicit mess.

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

    One thing I remember from somewhere is that *locality* is a key principle for code readability (as with all things in software, it's a principle, not something to overdo) and it seems DI really helps keep locality and so that's part of what helps keep it readable when it's used right.

  • @K14E
    @K14E 6 หลายเดือนก่อน

    love the smug ass incorrect pointer assumption that you then fail to prove. really nice dude *chefs kiss*. confidence inspiring

  • @tophy9865
    @tophy9865 11 หลายเดือนก่อน +2

    Us FPers staring at the OO crowd for giving some fancy name to passing data as a function argument.

    • @McZsh
      @McZsh 11 หลายเดือนก่อน +1

      It's not passing data, it's passing an implementation hidden behind a facade.
      Us FP guys asking, why a lambda aka strategy pattern isn't sufficient.

    • @tophy9865
      @tophy9865 11 หลายเดือนก่อน

      @@McZsh It's still passing data because, in OOP, implementations are data structures.

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

    Over many videos now I have come to love Prime's responses of affection when being handrd sustenance from his wife.

  • @stevenhe3462
    @stevenhe3462 10 หลายเดือนก่อน +10

    The downside is simply that you have no idea WTF is happening when you enter a new code base full of DI.

    • @vlad071096
      @vlad071096 5 หลายเดือนก่อน +1

      Yeah, just a bit of a downside.

    • @julkiewicz
      @julkiewicz 4 หลายเดือนก่อน +3

      That's not DI. That's just how reality works. When you enter a new code base by definition you don't know what it's doing. DI is not preventing you from finding out. It's like saying splitting code into multiple functions instead of having one giant block of code is preventing people from knowing what's going on. It's not.

    • @JBatesProductions
      @JBatesProductions 3 หลายเดือนก่อน

      Been there. It mega sucks.
      I try to avoid it unless necessary as it can become one of those things where you “just have to know” what’s happening.

    • @brandon14125
      @brandon14125 2 หลายเดือนก่อน

      Yeah not DI's fault tbh. New code based will always be somewhat confusing. Skill issue tbh. DI is one of the easiest solid principles to understand and follow in code imho

    • @JBatesProductions
      @JBatesProductions 2 หลายเดือนก่อน

      @@brandon14125 It’s not necessarily that it’s not easy to understand. But you have to understand the timing happening in a program holistically to know when and what a certain function should be performing. If you’re reading a single file, it’s sometimes not obvious that the function will not be performing what is initially assigned (Though, this can be made obvious by saying “my_func = lambda: None” with a comment or something).
      Further, it’s something can get out of control fast. A couple DI’s in a project? Fine. Dozens and dozens? Now you create a web that is likely very straightforward for the person who is writing it, but will take quite a while to sort through mentally.
      I also disagree with “new code bases will always be somewhat confusing.” That’s reducing something that’s very nuanced and can be judged on a curve to something thats black and white.

  • @complexity5545
    @complexity5545 11 หลายเดือนก่อน +1

    It's interesting to see how Slack programmers think and make solutions and all the high brow talk (to make it sound cool). Good video. I wouldn't have ever found or watched that guy's video.

  • @iNuchalHead
    @iNuchalHead 5 หลายเดือนก่อน

    17:10 DRY is aspirational. Don't does necessarily mean never. Nice to hear this!

  • @daleryanaldover6545
    @daleryanaldover6545 11 หลายเดือนก่อน

    I don't use TS but one way I solved having multiple sets of parameters is to have a lookup object table. The class must be constructed with, for example the storage service to be used. Then the object map provides autocompletion for the rest of the parameters using JSDoc. I don't have types for the class but it is well documented and autocompletion is a chef kiss.

  • @yongkangchia1993
    @yongkangchia1993 11 หลายเดือนก่อน

    man i have been waiting for this video to drop

  • @filippomenchini
    @filippomenchini 16 วันที่ผ่านมา

    Watching this video while eating is like eating with theprimagen and watching a computer science video together

  • @sealsharp
    @sealsharp 11 หลายเดือนก่อน

    21:57 Yes, this! I try to split components by those who work with data and those who work with timing and DI is nice for that.

  • @verb0ze
    @verb0ze 6 หลายเดือนก่อน

    I think the unit testing at 24:49 helps guard against regression. You assert behavior this way, and if tomorrow some dev comes in and decides to refactor because he doesn't like the way it was written, you'll catch any functional braking changes introduced. I also had a hard time with this time of test initially and found them useless, but on large projects they are very useful. Granted, e2e tests can also cover this, but you have to write a lot more code to cover possible scenarios because of all the other branching that can occur.

  • @genejas
    @genejas 11 หลายเดือนก่อน +6

    You can't EQ out clipping. The closest you're getting to removing clipping is using something like the declip module in izotope rx, which luckily is pretty painless to use

    • @wujujuju5111
      @wujujuju5111 4 หลายเดือนก่อน

      very good call rx is really nice

  • @chinoto1
    @chinoto1 6 หลายเดือนก่อน

    While doing Advent of Code (which I'll finish later...), I often deduplicated code that would only occur twice, but that's a bit contrived since you know that most of the code will overlap upfront.

  • @whaisonw2865
    @whaisonw2865 7 หลายเดือนก่อน +1

    15:55 This, so much this. One time a junior dev asked me at work about what my faviourite pattern was and I was just like: I don't know. I don't know the names of most patterns and principles. I am just asking myself what the clearest way is to tell my intend to the next person working on the project. How can I deliver that we have i.e. a few possible file types that need to be treated differently and how can I bake that into the type system. What is the most minimal solution for that. I know, a chain of if statements would also deliver the intend, but I don't know how to describe it better here

  • @jeremiedubuis5058
    @jeremiedubuis5058 11 หลายเดือนก่อน

    What is great with these videos is that these are the things new coders don't get enough of. They learn crappy quick solutions for easy ass projects and have to learn through experience how why and when to use a strategy pattern, a factory pattern, when to repeat or not to repeat. I've seen way too many express server examples expanded to become gigantic projects. Great job on CodeAesthetic's part. However yeah the issue is devs finding these hammers and then seeing everything as a nail. And yes the tests aren't testing anything typescript is already testing, the trouble in these scenarios is always having the right testing environement for e2e, you need a testing s3, a testing db, possibly a testing environement with the correct network connections between services... you need to reset that shit after the tests... it quickly becomes tedious.

  • @NuncNuncNuncNunc
    @NuncNuncNuncNunc 11 หลายเดือนก่อน

    "There's only one implementation of..." I know where this is going.
    @24:30 the sample test code can have multiple implementations - always happy path, always sad path, slow network, dropped network, etc

  • @at0mly
    @at0mly 6 หลายเดือนก่อน

    22:00 that's literally the entire concept behind languages like haskell- that's why you have pure functions that do your computation and then everything that interacts with the outside world happens through the io monad.

  • @TheBadFred
    @TheBadFred 10 หลายเดือนก่อน

    That reminds of the good old days with Spring writing XML configs for the dependency injection and annotation-voodoo-magic.

  • @ErazerPT
    @ErazerPT 11 หลายเดือนก่อน

    I see some value in DI/mock/tests in that you can ask the simple question "if y is working, why is caller x (or forward call z) blowing up? If it's not working, how does x (or z) handle it?". That simple yes/no will suffice for most things. It can even help with transient conditions if (at the boundaries) your parameters are reduced to a "generic" message passing object that both carries back the reply, if any, AND the state of the "operation". Your caller must now decide if when presented with "failed because of K" it wants to just fail, or handle the fail and retry, or....,etc.
    For me though, the true value is that it burns into you the idea of "interfaces at boundaries". Going forward, even when you're not using any of it, you start to instinctively "feel" when you crossed the line between (what should be) a and b components. Eventually you start NOT doing "monolithic" and also stay away from "abstraction i don't need". Hopefully...
    p.s. loved the SQLite mention. Had to "hard sell it" to my colleagues the other day and boy, was it a tough battle... What brought it home was the logical conclusion that if you wrap all of it in a "container", you can actually commit the state to a file at any point AND restore from that checkpoint at any time. The value of that when testing for "elusive bugs" can not be understated.
    p.p.s I only use SQLite when things are stable enough. First port of call is a simple "memory mapped" container that can be checkpoint'ed to/from a json file. It mimics "ideal conditions" and let's you test the code "if all was working properly". If so, and when the overall architecture is "stabilized" you move to the SQLite implementation so it's easier to do postmortem analysis if needed. Best part is that, using any of these (and client allowing), we can pull the live data from the SQLServer/MySQL/etc at any time with a tool, save it to a file, transfer it and our support team can play around with it to see what is happening when under clients state in an environment with full debug capabilities. Can save you a LOT of time over having someone checking it at the client's front end while someone else is sifting through backend logs, dead and live.

  • @renangarcia5710
    @renangarcia5710 11 หลายเดือนก่อน

    As a typescript developer (frontend) You won my like during the "as const" thing, that shit was great btw

  • @dan_le_brown
    @dan_le_brown 5 หลายเดือนก่อน

    "This is stupid!"
    * proceeds to smack his lap
    ...is such comedic gold

  • @dan_le_brown
    @dan_le_brown 5 หลายเดือนก่อน

    24:52 I'd argue that it's a way to test your critical paths or what i like to call "best case scenarios"-at the end of which you'd have provided value to your users

  • @rafaYouTabnecarollyn
    @rafaYouTabnecarollyn 11 หลายเดือนก่อน

    very good that he sends a crescendo out of nowhere lol

  • @ClaudioBrogliato
    @ClaudioBrogliato 11 หลายเดือนก่อน

    22:10, that's what Haskell claims to do through types (String vs IO(String))

  • @junior.flutter
    @junior.flutter 11 หลายเดือนก่อน

    Content provided by him is same as we have with different social media platforms but some how instead of decreasing our productivity it increases a little, reaction videos are common but these videos are productive

  • @RainbowVision
    @RainbowVision 5 หลายเดือนก่อน +1

    I think the difference between strategy and adapter pattern is that strategy uses different interchangable components for different outputs / side effects and adapter uses different interchangable components, but we expect the result to be the same whatever implementation you use.
    I do think he showed us more adapter patterns than strategy by that definition, but it is a very fine line nonetheless.

  • @Tony-dp1rl
    @Tony-dp1rl 11 หลายเดือนก่อน

    Unit testing I/O is usually just testing your Mock code works ... but code coverage numbers impress managers. :)

  • @shadowsir
    @shadowsir 3 หลายเดือนก่อน

    I loved that comment. Most of programming is using builder pattern and strategy pattern. I agree whole-heartedly

  • @vojtasks
    @vojtasks 28 วันที่ผ่านมา

    The problem with DI and OOP (which DI isn't the only thing used) is that, it relies heavily on abstractions. You always cook something over some gigantic amount of some object that all are abstractions over abstractions.

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

    Is he eating tangerines with bread slices? Absolute mad lad.

  • @maxolasersquad
    @maxolasersquad 7 หลายเดือนก่อน

    Testing is what finally sold me on DI as being good.

  • @lexer_
    @lexer_ 4 หลายเดือนก่อน

    Mocking is wonderful to simulate failures upstream or downstream of the thing you want to test. It's also useful if the actual task is way too expensive or slow to run. Otherwise you are probably better off not mocking.

  • @bunpasi
    @bunpasi 10 หลายเดือนก่อน

    You don't test a car by just going on the road, but you test the engine on a dyno, the tyres by checking the wear and slip in wet conditions, etc. You want to test thing individually to see where it goes wrong. Mocking and simulated environments can be convenient for this.
    But in general, testing to me is just taking the code that I already wrote to see if everything worked and saving it.

  • @josevargas686
    @josevargas686 11 หลายเดือนก่อน +2

    In elixir there is pattern matching on function args. It removes all of the if/else and makes it duper easy to parametrize behavior... Uh i mean, "inject dependencies" (did I use the fancy words correctly? I need to impress the Jr devs while making them feel dumb for not understanding my big thoughts right away)

    • @josevargas686
      @josevargas686 11 หลายเดือนก่อน

      It also makes it much more easy to understand when you declare the struct type on the pattern. As opposed to declaring some generic interface and then trying to figure out which classes are implementing this interface.

    • @verified_tinker1818
      @verified_tinker1818 11 หลายเดือนก่อน

      I actually prefer a straightforward switch/match statement instead of hunting for another declaration of the same function buried somewhere in the file.

  • @stroiman.development
    @stroiman.development 2 หลายเดือนก่อน

    This example uses dependency injection as a way to implement the strategy pattern, which does make sense to some degree (Was there a test verifying that the correct dependencies are injected in the production version? A pretty crucial part of the solution)
    But for the vast majority of code that I've seen, there is NO strategy - no alternate implementations of behaviour (in production code). It's just, the DbContext is injected into the UserRepository. The UserRepository is injected into the UserManager. The UserManager is injected into the UserController. And then each of these are tested independently with a ludicrous amount of mocking (I've seen implementations where the very thing to test had been mocked out).
    The hip bone's connected to the ...

  • @dadbod591
    @dadbod591 11 หลายเดือนก่อน

    "is mayonnaise a strategy?"
    "I think so"
    😂

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

    DRY...man I'm using Dapper on one of our projects...I don't even remember what the using statement looks like because I wrote it just once, and copy-pasted it a million times whenever database requests were needed.

  • @andygarfield6529
    @andygarfield6529 11 หลายเดือนก่อน +1

    I got a DoorDash ad right after the Wifeagen brought him food. “You know… you can have your food delivered too…”

  • @Bourn77
    @Bourn77 11 หลายเดือนก่อน +2

    I cant imagine not using DI in C#, usage of factories like in Java is not required at all in C#, we can use a nice DI container like Autofac,Ninjact etc for Strategy pattern (multiple implementations of same Interface) and resolve them at runtime using a key. In .NET 8,keyed resolve is also supported bt default DI container.

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

    0:30 lmao and here i was like im doing it wrong

  • @starlederer
    @starlederer 11 หลายเดือนก่อน +8

    I am fully on board with Code Aesthetic with this one. I don't like it when people give simple things impressive names. It is indeed no "dependency injection", it is passing a stupid thing to a function and so is it not "strategy pattern", it is a literal stupid if statement

  • @Lemmy4555
    @Lemmy4555 11 หลายเดือนก่อน +30

    All of these patterns that force you to write tons of classes to do anything and leave you bloated with Managers, Generators, Runners, Loaders, etc., only make sense for the person who writes them. In reality, they are extremely hard to debug, and all of this encapsulation makes it impossible to know what will happen without debugging at runtime. I started my career with Java and used all of these patterns. But then I grew up and stopped using any of them. Today, I just write a simple function, pass the parameters, and reduce all of the decision logic for using one strategy or another to "if" or "switch" statements. I only use classes in very specific cases for self-contained stuff. I almost never write the words "extends" or "implements" anymore, and my life is much better for it. :)

    • @gotxe
      @gotxe 11 หลายเดือนก่อน +3

      💯 this.

    • @deadvirgin428
      @deadvirgin428 11 หลายเดือนก่อน

      Gigachad. Genuinely I don't think this CodeAesthetic guy has made a single good video, but he makes cool visuals so people assume he's right lol.

    • @etodemerzel2627
      @etodemerzel2627 11 หลายเดือนก่อน

      Well said!

    • @minhduccao9955
      @minhduccao9955 10 หลายเดือนก่อน

      Whats language you using now

    • @Lemmy4555
      @Lemmy4555 10 หลายเดือนก่อน

      @@minhduccao9955 ts/python

  • @poeticjystice
    @poeticjystice 11 หลายเดือนก่อน

    This video pretty much sums up my job

  • @helleye311
    @helleye311 11 หลายเดือนก่อน +2

    Finally someone said it, DRY only if it actually repeats, not just randomly happens to be the same in two places. I only really extract things if they're identical in 3+ places, or quite similar in 5+ places.
    Also, DI very good if you know what you're doing. Especially with typescript or other fake-strict languages, you don't actually need an interface and a class, you just say
    storage: { store: (item: something)=>Promise} and provide an object that has a store method taking something returning a promise, and what happens from there is irrelevant. You probably will have classes or at least some helpers for S3 storage and FTP storage, but you don't need a MockStorage class for testing, you just inline that shit. Have some weird edge case? Inline that shit. It's quite pleasant to work with if you don't have to explicitly state every behavior and can just wing it (again, for dev/testing only, wouldn't recommend in production, but then again it probably won't break, just not as easy to maintain). And you can mock write a Harder Drive implementation.

    • @jboss1073
      @jboss1073 11 หลายเดือนก่อน

      Hahahah fake-strict languages I love it.

    • @depafrom5277
      @depafrom5277 11 หลายเดือนก่อน

      100% DRY or nothing, if you are unable to reach 100% then there is something wrong with your design... and then there is code maintenance, tests etc.

    • @Muskar2
      @Muskar2 11 หลายเดือนก่อน

      @@depafrom5277 I think it's quite the opposite. In my experience, 100% DRY means you turn all your code into thousands of small generalized modules, which makes it much harder to maintain - because the uses of the modules/functions are often slightly different and then it becomes extremely complicated to be aware of the relevant context for specific real world scenarios. That wouldn't happen if you just have the relevant code and data right all in the same place that deals with the specific scenario - even if similar logic happens elsewhere. The parts of your application that are likely to change doesn't need tons of separation of concern and abstraction layers.

    • @depafrom5277
      @depafrom5277 11 หลายเดือนก่อน

      @@Muskar2 Yeah, I guess some languages and frameworks lends themselves better to DRY than others.

  • @Waitwhat469
    @Waitwhat469 10 หลายเดือนก่อน

    This seems like a natural step towards microservice architecture design too, at least to me.

  • @outwithrealitytoo
    @outwithrealitytoo 5 หลายเดือนก่อน

    In the land of C: a struct type containing - an enum to switch on and a "union of struct types" for the parameters... Add in a test/mock type and its all good for unit tests. "What if someone passes the wrong parameter structure?" well, then you have personal and integration problems that compiler checks won't save you from.
    Abstract the APIs behind open,read/write close file interface a la Unix...
    What about the weird and wonderful things that can go wrong with each storage method? Generally "something went wrong" is important for control flow. "What went wrong?" that's a debug issue (and that is why Golang error handling works like it does). In my experience... code that properly handles something going wrong at any time, is rare enough... and using "what went wrong" in control flow is abused or only partially handled.

  • @liquidcode1704
    @liquidcode1704 11 หลายเดือนก่อน +1

    "I am mustafa, and I am the code you be refactoring now........ damn, three times"

  • @teodor-valentinmaxim8204
    @teodor-valentinmaxim8204 11 หลายเดือนก่อน

    At this point, this man intentionally forgets to turn of alerts, just so he can say that he forgot

  • @neociber24
    @neociber24 11 หลายเดือนก่อน

    Is this the mustache man works at Netflix? Subscribed.

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

    Whats your opinion on e2e testing mircroservices or approach? I'd like to use test containers for integration test but it's an uphill battle to get a sign off on it for the enterprise version. I do agree that mocking usually causes issues and you end up always finding bugs due to something external not working as expected. For e2e we had to build out a microservice to test all the other services which I'm not a fan of.

  • @sd_pjwal
    @sd_pjwal 4 หลายเดือนก่อน

    Polymorphism is an OO contruct oft utilized in patterns. It is simply the ability for the caller to execute code without knowing the subclass implementation. That's it.

  • @NoOne-fe3gc
    @NoOne-fe3gc 4 หลายเดือนก่อน

    A lot of this can be dumbed down and distilled to this simple thought: Whenever you are implementing a functinality, always keep in mind "who's concern is this", e.g. Where the data will be stored, how the data will be scanned, and even WHAT the data is, is NOT a concern of the UploadRequest, so it SHOULDN'T KNOW anything about

  • @abysmallytall
    @abysmallytall 11 หลายเดือนก่อน +1

    S3 the largest graveyard? Confluence was right there, though.

  • @k98killer
    @k98killer 11 หลายเดือนก่อน +3

    If you use precondition checks, you can significantly narrow the possible error surface of your code, thus obviating the need for high levels of testing for errors -- you just have to document that supplying invalid arguments/inputs to your code will result in whatever errors your precondition checks return/raise. This also makes it really easy for users of your code to understand what they did wrong because you explicitly tell them what they did wrong.

  • @kuhaniresti
    @kuhaniresti 8 หลายเดือนก่อน

    You can use structured context object and pass that arround in cascaded calls, im using this strategy in FragmentJS

  • @keoghanwhimsically2268
    @keoghanwhimsically2268 5 หลายเดือนก่อน

    0:43 Just starting out, that’s not what “dependency injection” was. That’s just delegation, or what you could call parameterized composition, or even just configuration. When “dependency injection” began to be discussed at all, it was about configuring code dependencies from outside of the call path, say via XML configuration files. That’s why it was called “injection”. “Delegation” and “configuration” are much older concepts. For example, if you have configurable service providers, that, in your call path, selects a service provider based on on a configuration property, that was not called “dependency injection”. For it to be called “injection”, the injector would replace runtime calls to a particular service, say described by an interface, with the desired implementation, with the original code being none the wiser.
    If DI is defined this way today, it seems like its proponents trying to grab ground that doesn’t belong to them. If you want to call it “dependency management”, have at it. But by trying to redefine “dependency injection” in this way, you’re trying to wave away why so many saner engineers thought DI was unworkable in the first place.

  • @andrew_ray
    @andrew_ray 28 วันที่ผ่านมา

    7:58 You can have a pointer to a constant, but you need to give the type implicitly because "as const" forces TS to infer a narrow type. let foo = { a: 5 } as const; gives foo the type {a : 5}, to which { a: 4 } is not assignable.

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

    Chat so eager to admit their blatant refusal to learn and their propensity to copy and paste code

  • @flipflopsn
    @flipflopsn 4 หลายเดือนก่อน

    "What's WebDAV" made my cry so hard because I didn't know it either until I had to re-do a whole "FileTransfer" Lib in our Common Lib where I had to reimplement all the connectivity of the possible endpoints for filetransfer, including FTB, SFTP and "ofc" WebDAV. WebDAV nearly made me cry, maybe it was our infra or WebDAV is just coming literally out of hell, idk haha.

  • @bugfacedog44
    @bugfacedog44 4 หลายเดือนก่อน

    It looks like Manim animation to me (which is indeed a Python library). It was developed by 3Blue1Brown for all of his math videos.

  • @k98killer
    @k98killer 11 หลายเดือนก่อน

    I like including dependency injection but supplying a default implementation where appropriate.

  • @tunafllsh
    @tunafllsh 11 หลายเดือนก่อน

    Exactly 27:20 start with the bad stuff and then fix it. That's the way! That's how you get your green activity on your github profile.

  • @farqueueman
    @farqueueman 11 หลายเดือนก่อน +5

    I prefer the FOB (Fauci-Ouchi Booster) design pattern for all my bwazingly fwast needs ❤

    • @ThePrimeTimeagen
      @ThePrimeTimeagen  11 หลายเดือนก่อน

      how does one learn about this FOB?

    • @farqueueman
      @farqueueman 11 หลายเดือนก่อน +1

      @@ThePrimeTimeagen you don't learn about it! That requires critical thinking! You just use it! FOB is backed up by the (computer) science and has already been certified useful and true by the fact (type) checkers.

    • @SimGunther
      @SimGunther 11 หลายเดือนก่อน

      ​@@ThePrimeTimeagen Schalk and Hawn (1931) First Report of Infectious Bronchitis in North Dakota
      Enjoy that journal journey

    • @andricode
      @andricode 11 หลายเดือนก่อน

      ​By wanting to.
      If you feel it'll be more comfortable for you, get used to it and then do all that * efficient * stuff

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

    The separation of logic and I/O is the ports and adapters or hexagonal architecture pattern and yes, it's very useful. But also it can be taken to an extreme and become a nightmare. Don't ask me how I know this 😅

  • @samuelwaller4924
    @samuelwaller4924 7 หลายเดือนก่อน

    literally just watched that video, the audio is fine its you lol

  •  11 หลายเดือนก่อน

    That last advice!

  • @mmmhorsesteaks
    @mmmhorsesteaks 10 หลายเดือนก่อน +7

    Fun fact - if you start your script with 'import this' you'll find python is fast enough in 90% of cases.

  • @davidengelmann1636
    @davidengelmann1636 11 หลายเดือนก่อน

    I cant believe he wrote that whole s3 test to prove he can write to disk

  • @appology9102
    @appology9102 3 หลายเดือนก่อน

    DI without a container is wild.