Advanced Dependency Injection without classes - Fun Fun Function

  Рет қаралды 31,817

Fun Fun Function

Fun Fun Function

Күн бұрын

Пікірлер: 122
@dmitryplatonov
@dmitryplatonov 7 жыл бұрын
You can improve your last example doing separate functions and then have function aggregating them: const f1 = connection => id => something1; const f2 = connection => id => something2; const f3 = (connection, emailService) => id => something3; const makeFs = (connection, emailService ) => ({ f1: f1(connection), f2: f2(connection), f3: f3(connection, emailService), }); This pattern shows dependencies and allows to use functions separately, reducing boilerplate at the same time.
@funfunfunction
@funfunfunction 7 жыл бұрын
Wow, that's a great idea!!! Thanks!
@CrapE_DM
@CrapE_DM 7 жыл бұрын
There are only 2 difficult things in programming: cache invalidation, naming things, and off-by-one errors.
@funfunfunction
@funfunfunction 7 жыл бұрын
+Jacob Zimmerman ahahhaha
@dacianspinu2514
@dacianspinu2514 7 жыл бұрын
That is so good!
@jeffparent2159
@jeffparent2159 7 жыл бұрын
This is why I've embraced functional programming over OO. All of the extra "stuff" in OO is either a necessity or a huge waste of time depending on your ability to predict the future. And I'm notorious for picking the wrong future. Once I started writing more Haskell and Scheme and less C++/C#/Java I found that my efficiency...or better yet, my lack of scrapping and redoing code got so much better when I started developing functional over OO. The act of refactoring became finding slightly more efficient ways of doing things, rather than cleaning up all the crap I did wrong.
@jacksonlenhartmusic
@jacksonlenhartmusic 7 жыл бұрын
My favorite channel on KZbin right now. Perfect combination of entertainment and education. Well done sir!!!
@patrickisboard
@patrickisboard 6 жыл бұрын
I hope these topics (functional programming in particular) are required for undergraduates in the near future. Especially near the beginning of the major where OOP is drilled into students.There's so much time and heartache I could have eliminated professionally if I had known about these techniques sooner. Thanks for the entertaining and amazingly clear videos! It's obvious you love doing it. :)
@beatazoldi1020
@beatazoldi1020 7 жыл бұрын
JavaScript with Jack Frost ❄
@PeerReynders
@PeerReynders 7 жыл бұрын
Somehow expected an obligatory reference to “venerable master Qc Na and his student, Anton” - “Foolish pupil - objects are merely a poor man's closures." - “When will you learn? Closures are a poor man's object." (RE: What's so cool about Scheme? Anton van Straaten, 4 Jun 2003; referencing Christian Queinnec’s “Lisp in Small Pieces” (Qc) and “objects are a poor man's closures” attributed to Norman Adams (Na)) Repetition: DRY (don’t repeat yourself) was publicized in the “The Pragmatic Programmer” in 1999. But it also had a very clearly stated motivation: Every piece of KNOWLEDGE must have a single, unambiguous, authoritative representation within a system. So the principle is also sometimes referred to as SPOT (Single Point of Truth). So focusing just on DUPLICATION is overly simplistic and eliminating it everywhere is simply dogmatic. Principles and guidelines typically have circumstances when they apply and consequences when they are applied. There are circumstances where code may look the same but exists for entirely different reasons - both areas may need the freedom to evolve in entirely different directions. Also eliminating duplication increases coupling - in some cases that is tolerable or even desirable, in other cases it is not. (“Development by Slogan DRY”; “To DRY or not to DRY, it is a matter of boundaries”)
@the_crius
@the_crius 7 жыл бұрын
I like to think that programming is a form of art. And what you said about having the structure emerges remembered to me what seems that Michelangelo said once: Each block of stone has a statue inside it and it is the task of the sculptor to find out.
@wh33lers
@wh33lers 7 жыл бұрын
Claudio Vallesi you sould watch this talk kzbin.info/www/bejne/p4G9ioRtodKCeMk
@__gustavonovaes
@__gustavonovaes 6 жыл бұрын
That's a perfect example to this quote: "First, solve the problem. Then, write the code." John Johnson.
@danilovegap
@danilovegap 7 жыл бұрын
Just passing by to flatter that awesome hair style
@DanielFlint
@DanielFlint 7 жыл бұрын
The two hardest things in programming: naming things, caching, and off-by-one errors ;)
@psprague
@psprague 7 жыл бұрын
Hi mpj, greetings from the Czech Republic. Even though I'm more a PHP developer, I really like JavaScript and develop in it as well. Your videos are very enlightening and most of the stuff I can relate to even in other languages than JS. I really appreciate your effort, keep up the good work!
@staschernov2762
@staschernov2762 7 жыл бұрын
Hair color goes nicely with VS Code color scheme :)
@sreid70
@sreid70 7 жыл бұрын
Whaaaaat! I always learn so much watching your videos! 8:32 - 9:30 in the video. Was a little foggy about destructuring , but now its clear. Thanks for the great videos.
@redgreenbluehex
@redgreenbluehex 7 жыл бұрын
New Hair looks great. Thanks for another great episode! Love what you're doing for the community.
@stevenfrieson3228
@stevenfrieson3228 6 жыл бұрын
This was super helpful for me. I've started a new project and have been reading and watching everything I can about IoC and DI, as well as reading Code Complete by Steve McConnell. Trying to balance "doing it right" with "move fast and break things" so I can actually launch something before I tire of this side project. Almost everything you've said in this video has been what I've been going through, but not only has this been slowing me down tremendously, but even more specifically, it's been making writing tests even harder because I have to mock dependency which is laborious, repetitive, and fragile since the deps change, so the mock has to change. Also to echo another comment, I totally agree with your comments about being hard to predict the future, but also the first 5 chapters of Code Complete stress the importance of architecting/designing upfront. I'm not saying anyone is wrong or right. Just saying how much I appreciate these videos and how I can always seem to find one that meets me exactly where I am as I've been growing. Thanks for helping me form opinions.
@fjfurtado
@fjfurtado 7 жыл бұрын
As unit testing is one of the main reasons to use dependency injection, I think it would be a good ideia for you to make an analysis on how each of the scenarios stands against unit testing.
@luxtethys4782
@luxtethys4782 7 жыл бұрын
especially testing the component that uses 'user-utils'
@impankratov
@impankratov 7 жыл бұрын
I've actually thought that @mpj will cover testing in this video.
@alegutierrezmusic
@alegutierrezmusic 7 жыл бұрын
Testing promises itself is not easy IMHO. I have used spies and mocha as promised lib when is simple. I would like to know what is your method on such cases?
@impankratov
@impankratov 7 жыл бұрын
Usually mocha & chai is enough to test promises (sometimes you can utilize chai-as-promised plugin).
@julienjamet
@julienjamet 5 жыл бұрын
at 9:27 const makeBanUserWithService= emailService => connection => makeBanUser(connection, emailService) const factories = [ makeCreateUser, makeDeleteUser, makeUpdateUser, makeBanUserWithService(emailService) ]
@booskie11
@booskie11 7 жыл бұрын
Excellent video. The main takeaway that I think all devs should start to embrace (including me) is that we need to force ourselves to allow and embrace duplication for a period of time until we can see the true pattern emerge. As you so eloquently stated, we humans can't predict the future. Only until we fully understand our present state can we improve upon it and better position ourselves for the future.
@nick1wow
@nick1wow 7 жыл бұрын
Nice vid, mpj! I agree with you. Some questions: When working with a team, isn't it dangerous that the 'other-services' file will just become a dump of functions that people use as they just don't want to waste time refactoring at that time or the file gets too large that no one knows everything that is inside? And after you find a decent pattern, how would you refactor those functions? Classes, factories, module? Probably depends on the pattern you found, but it would be interesting to understand when to use each.
@AngusMcIntyre
@AngusMcIntyre 7 жыл бұрын
I am currently experiencing this organisation issue with my latest big c# project. Recently I refactored big chunks away as the separation became clear. Really good method that I try to impress upon my colleagues. Makes me jealous of JavaScript 😀
@quterma
@quterma 3 жыл бұрын
great one! Thank you, MPJ!
@dailydev4994
@dailydev4994 7 жыл бұрын
Hello MPJ! Wouldn't a DI Container be a good way to solve this? It only injects the required parameters and you don't have to update thins everywhere when you make a change.
@modiddymo
@modiddymo 7 жыл бұрын
Hey, big fan of the show and always learning from you. I love what you're saying about letting the patterns emerge here. I think that needs to be tempered with some knowledge of established patterns and the idea that consistency is key. If I was writing the sample code you wrote here, I would quickly create a User class and would keep it simple. I come from an MVC background and I like the idea of models housing my app's business logic. I wouldn't tighten the bolts too tight though and would let more patterns emerge over time, and refactor when needed. I stopped using semicolons after writing Swift and watching your episode on semicolon injection. Keep up the good work!
@andrewalbright4529
@andrewalbright4529 7 жыл бұрын
I very much agree with the idea of discovering patterns as they emerge organically. I have read the same idea written differently (such as: "early optimization is bad"), but thinking from the angle you present here has given me a deeper understanding of the topic as a whole. Do you have (or know of) any videos in which you discuss this idea further? Thank you for the excellent content.
@curiousprogrammer90
@curiousprogrammer90 7 жыл бұрын
Serbian candy! Nice! Greets from Serbia :)
@mmsikoras
@mmsikoras 7 жыл бұрын
MPJ - it was great like always. I really like the conception, but I have some doubts about Your theory related to predicting the future. I agree that predicting the future is not possible, but I don't agree that we should not even try. Every app needs some architecture on the beginning of development, some file structure, some places where things are grouped. Without those assumptions we would always start with a flat structure and all files placed in it, and this is very bad idea. Even in your example, you predicted that you will have some functions in one file, and why, if you can not predict nothing? If we go into that and in some point of time, we will know that now it's a moment when those things should be grouped, then it means that refactoring will be needed. What is the improvement, if in case you try to predict or not, the refactoring is something certain , though. In my opinion basic conception and architecture is a "must have" in every project. Even if it is wrong, and will need an adjustment, it is better than nothing. Going back into example, for me, returning an object from high-order factory function with all needed functions would be more clear to use, than returning list of not connected to each other functions as you have shown. Instead of make{Something}User in all cases we would have userRepository.add(name), userRepository.delete(id) etc.. We tread object as a structure for grouping functions, and I am fully ok with that. Thanks again for great material every week!
@Voltra_
@Voltra_ 7 жыл бұрын
I don't really understand why people could have a hard time with dependency injection, the principle is basically "Pass whatever you will use as a parameter"
@masterbonzala
@masterbonzala 6 жыл бұрын
17:40 that looks much better considering the open/closed principle: open for extension, closed for modification
@MohamedCherifBOUCHELAGHEMdz23
@MohamedCherifBOUCHELAGHEMdz23 6 жыл бұрын
What I used to do is instead of predicting the future, I implement use cases approach depending on the discussion with customers/stackholders
@trabpukcip1177
@trabpukcip1177 7 жыл бұрын
I liked it better when you would be holding your freshly made cup of "coffee", after the intro. But that part is still my favorite :D
@TimJohns
@TimJohns 5 жыл бұрын
MPJ - thanks for putting this together! I was recently pointed to it by a coworker. The "how" to avoid premature grouping (as classes) in the first half of the video was awesome, as was the "why" to avoid premature grouping near the end. I think I'm missing a step in my thinking though - the particular "how" techniques shown here (i.e. passing the dependencies as closures to stand-alone factory functions) seems complex to me compared to passing the the dependencies directly to the stand-alone functions, which would also seem to address some of the encapsulation issues you described. I'm curious if you have another similar video that contrasts the technique of passing the dependencies into lowest-order functions directly, rather than using a higher order function as a factory, and using closure to pass them?
@funfunfunction
@funfunfunction 5 жыл бұрын
The problem is that if the api of a function requires you to pass all dependencies at call time you end up with insanely long function signatures at the top level.
@piq-dg3vz
@piq-dg3vz 7 жыл бұрын
Code that is too DRY is brittle "Inversion of control is just a pretentious way of saying parameterizing the constructor"
@andresfelipemedinavalencia4660
@andresfelipemedinavalencia4660 7 жыл бұрын
great as always. I have been following you for a good time and you always talk about "let duplication arise" and all that kind of stuff. I think would be great if you come with a video about actually javascript architecture, perhaps more focused on the beginning of a projects, I mean, I get the point of let duplication arise, but I guess one has to start with something in a project, some initial structure, how do you handle this initial structure before start organizing the things?... how do the requirements play here?
@pedrovsr_
@pedrovsr_ 6 жыл бұрын
man I LOVE this opening
@CliffStamp
@CliffStamp 7 жыл бұрын
Nice video, that was the exact question I had after the last video, multiple methods.
@adamseckel7480
@adamseckel7480 7 жыл бұрын
I am LIVING for your new haircut! 🙏🙏🙏🙏
@fjfurtado
@fjfurtado 7 жыл бұрын
You say a lot of times that one should let the duplication grow before attempting any optimization. That may let one to think that refactoring should only be done on the long run. I think that refactoring should be a continuos task so as to keep your application clean and readable.
@funfunfunction
@funfunfunction 7 жыл бұрын
+Francisco Furtado it's a tool to achieve certain goals, of which removing excessive duplication is one. While it is good to not postpone for too long and go over the code for potential refactoring every time we make a change, its important to remember that refactoring doesn't have any value itself, we do it to achieve certain goals. Just like we need to hold ourselves back to add features in a codebase that needs refactoring, we also need to restrain ourselves to do refactoring before there is an obvious path forward with the refactoring.
@fjfurtado
@fjfurtado 7 жыл бұрын
Fun Fun Function I really like the spirit of your videos so, thanks for replying to my comment :) I think that you say refactoring as no value when you really mean to say, it doesn't push the app forward. I agree with that. But I think refactoring as a lot of value. Most of the times it's overall goal is very simple, keep the code clean and readable. You know you will lose a lot of time reading your code in the future, you know your team will lose a lot of time reading your code in the future. I don't know anyone who creates perfect code the first try. If you have your code properly covered by unit testing you should not be afraid to refactor now and then later until you get it right. Why not invest a bit of time now so as to spare a headache to the next guy? Maybe yourself :)
@CliffStamp
@CliffStamp 7 жыл бұрын
At about 24 mins is one of the clearest objections to OO.
@immerification
@immerification 7 жыл бұрын
Thanks for sharing! What about using common programming approaches for OOP such as open-closed principle and single responsibility... I mean the layers - classes - could be tiny and doing only 1 thing, if in case you need to add functionality in the future - extend the class, inheritance, or as in this case decorators could solve the problem, which add additional behavior - like logging.
@funfunfunction
@funfunfunction 7 жыл бұрын
+Michael K. Decorators solve a problem that only classes have - when dealing with functions we can just use higher order functions to do what decorators do. And yes, classes CAN be tiny. But my personal feeling is that small functions feel more natural than small classes. It just seems like the function is in its natural state when it's a single small thing, and I don't feel that way with classes, they seem silly when they have just one method.
@immerification
@immerification 7 жыл бұрын
by 1 thing I've meant set of logic e.g. domain business logic (like CRUD for this particular case). Inheritance is natural for oop, just using the logic from the base class and extend it in inheritors using new dependencies, in such case you have only the dependencies in the classes you need, not overwhelming them with what they should not do. I understand your idea of functional approach but just trying to say that with classes there are proven ways how to deal with it.
@funfunfunction
@funfunfunction 7 жыл бұрын
+Michael K. But that's EXACTLY the problem. You've now started grouping things as CRUD but as I'm trying to show in the example, we see that the reality turns out more complicated, with more operations happening. Perhaps I could have thought of a better example, but do you see how the class just nudges you into thinking "ball of CRUD" because it must be a group? Inheritance is a dreadfully bad pattern (I talk about it in the composition video) and is yet another way that classes incentivize predicting the future prematurely. It is a pattern that is massively overused and not criticized enough.
@immerification
@immerification 7 жыл бұрын
I'm not thinking about not needed grouping, I think of responsibility of the class, the domain context (also could be a micro service context), if the things go more complicated you need to think who is responsible for doing one or another thing, and set the right dependency chain. Usually one needs to pass several steps in order to collect the information about the domain model in general as you've mentioned - having duplication, bad utils and managers classes, but later or sooner they become just decomposed. For sure one should not create early abstractions and inheritance prematurely because they will just tie the hands for the later changes.
@donfrolic
@donfrolic 7 жыл бұрын
Thanks for sharing your experiences and train of thoughts, as always (almost), in a clear and coherent way :)
@amoskane
@amoskane 5 жыл бұрын
Wait, what HAPPENED at 11:35 ??? How many hours passed?
@Jannic91
@Jannic91 6 жыл бұрын
I totally agree with you on having to create classes for simple functions is annoying but at 25:00 isn't that kind of similar to choosing a class name? We have to think of an module name instead of a class. We could also name our class OtherServices
@sweLogan
@sweLogan 7 жыл бұрын
Love the hair! Realy bumb out for missing the nordicjs.com
@TheOlian04
@TheOlian04 7 жыл бұрын
Krister Johansson the vods will show up on their KZbin in a bit
@ProgramArtist
@ProgramArtist 7 жыл бұрын
24:15: So far I didn't really see a real reason why using classes to group things is bad...Good point! 25:00: There was an episode where you talked about naming stuff and how you hate giving general names that don't mean anything. How does 'other-services' is not one of those names? Do you actually commit-push those for other people to use? Because it seems that if all people would do that and wait for the patterns to emerge we would end up with many meaningless files and couldn't really find anything
@funfunfunction
@funfunfunction 7 жыл бұрын
+ProgramArtist other-services is a non-name. Perhaps "unnamed" would have been better or "unsorted" or "not-yet-sorted" or "to-be-sorted". The purpose is a holding pen before sorting.
@ProgramArtist
@ProgramArtist 7 жыл бұрын
Fun Fun Function yes I understood what you ment, just feels like it would explode if everyone in the project would do the same thing. You'd forget to rename those files and people many files would be 'decide-name-later', 'temp-name', 'how-should-I-name-my-son'
@Zephyr85
@Zephyr85 7 жыл бұрын
Great video, thanks! I'm curious how you would go about using DI within a express (or similar) route handler, to make testing those easier?
@chris-eg
@chris-eg 7 жыл бұрын
Cool vid another issue that could comeup is if you had two imports e.g (DatabaseUtils and ProfileUtils), written by 2 diiferent coders and both had a 'createUser' function in each one there could be a name collision... (which can be fixed, but you are 'interfering' with someonelses code)
@vladimiry4441
@vladimiry4441 7 жыл бұрын
This code is about the inversion of control ideas, that is a similarity with DI. But the code looks more like an old school Factory pattern, not the DI, as you don't have the DI container here. So in my opinion the correct title would be "Inversion of control without classes". So you create the instances manually and then pass the references manually - that's not the DI idea. You would have gotten the DI having the DI container thing implemented that would automatically scan all the possible implementations, then instantiate needed implementations and then inject them - everything happens automatically and so you get more clear code (usually the less custom code the better). That means that avoiding classes you would have to introduce some unique marker for marking your functions in order to make DI container unambiguously distinguish the available implementations (ES 7 decorators with reflect-metadata? = Angular 2+). You would probably have to mark all the functions with one purpose by one mark, and other functions by other marks, etc as there might more than a one implementation available for the single purpose. Normally you use an interfaces working with DI, operating by interfaces in the code, and DI mechanism automatically injects the actual instances from the DI container, but you prefer to avoid OOP/classes ideas.
@funfunfunction
@funfunfunction 7 жыл бұрын
No, I strongly reject the idea that DI needs a DI container. DI containers are used way too widely to do way too complicated injection (and often bad injection patterns, circumventing dependency inversion). DI containers should be the exception, not the rule. Keep things simple.
@vladimiry4441
@vladimiry4441 7 жыл бұрын
Sure, but then this is more like a factory pattern, not a real DI thing. Anyway thanks for sharing.
@bobkelso5681
@bobkelso5681 7 жыл бұрын
The hair looks like a 14yo punk :) Great video. Thanks for making monday a good day. Now that we fund your patreon, can we expect to get more videos than once peer week?
@feihcsim7045
@feihcsim7045 7 жыл бұрын
and more hairstyles !
@ryanbach937
@ryanbach937 7 жыл бұрын
yasss yasss... the colored hair. Now you're a true KZbin star :P
@tokyoyojohanna2989
@tokyoyojohanna2989 7 жыл бұрын
Loving the hair and the new intro(?)!!
@jaapbadlands
@jaapbadlands 7 жыл бұрын
Thanks for the vid. I felt like it was heading somewhere with a final solution to the dependency injection problems you highlighted in your examples, but you never quite got there? Also the anti-class example was a bit unconvincing, I'd have made that a User class with make, delete, ban etc as method. I don't think it's that hard to see early on that a user is an important entity within the app and use that as the basis of your class.
@luxtethys4782
@luxtethys4782 7 жыл бұрын
Although it's adding inheritance, here's a little example on how your initial entity definition can be decided too early medium.com/humans-create-software/composition-over-inheritance-cb6f88070205
@jaapbadlands
@jaapbadlands 7 жыл бұрын
Ahh, ok that's more convincing than in this video. Thanks for sharing and thanks MPJ for the great channel.
@VasylBoroviak
@VasylBoroviak 7 жыл бұрын
Omg MPJ. I gonna blog post about this video. Beware. 😎
@funfunfunction
@funfunfunction 7 жыл бұрын
+Vasyl Boroviak do it!!!
@VasylBoroviak
@VasylBoroviak 7 жыл бұрын
Did it! 8 minutes read. See the link under the tweet which announced this video. :) Sorry if it's written in an insulting way. Please, point me if I offend you or being rude. English is the third language I speak and loosely write.
@nayaleezy
@nayaleezy 7 жыл бұрын
hmmm class tooling seems like a near perfect fit for your crud service needs
@srdjanmarjanovic
@srdjanmarjanovic 7 жыл бұрын
WHAT WHAT! Soko ŠTARK is in the house?! :D Btw, I suppose the guy's name was Nemanja - pronounced like nem-an-yah :)
@alexongg
@alexongg 7 жыл бұрын
Why did you switch from atom to vscode?
@funfunfunction
@funfunfunction 7 жыл бұрын
+Alejandro Corredor better presets. I like an editor that I don't need to configure or install stuff on.
@AlanBem
@AlanBem 7 жыл бұрын
So, in order to not use classes, you have created (pseudo) static class.....
@funfunfunction
@funfunfunction 7 жыл бұрын
+Alan Bem You can view it that way. You can also view it in the exact opposite way - that because people didn't understand closures and higher order functions classes were uncomfortably welded into JavaScript.
@zeeeeeman
@zeeeeeman 7 жыл бұрын
Alan Bem - I agree with you. I'm struggling to see any advantages of the FP way in this example.
@pontuscolliander2996
@pontuscolliander2996 7 жыл бұрын
What are your thoughts on grouping the functions like you did initially with a closure on connection, but passing certain arguments when only one method needs something specific like a mailService? As an example banUser would take a mailService as an argument here: const makeUserUtils = connection => ({ createUser: name => connection.table('users').insert({ is_new: true, full_name: name, }).then(user => user.id), deleteUser: id => connection.table('users').remove(id), banUser: (id, mailService) => connection.table('users').update({ $set: { banned: true } }).then(() => mailService('joe@gmail.com', 'i banned you')), });
@DaveSibiski
@DaveSibiski 6 жыл бұрын
The problem with this is that every caller of banUser now has to know about mailService (and know how to instantiate it, which could require lots of configuration details). The point of DI at this level is to construct together everything your system needs at one point (preferably when your app loads) so that they the rest of your system already has everything it needs at runtime. "Push 'new' up the call stack" - quote from J.B. Rainsberger - blog.thecodewhisperer.com/permalink/consequences-of-dependency-inversion-principle
@JoseFlores-hk1xd
@JoseFlores-hk1xd 7 жыл бұрын
Awesome video intro!
@justfly1984
@justfly1984 7 жыл бұрын
Thank you!
@rebornreaper194
@rebornreaper194 6 жыл бұрын
Great video!!! :)
@unknowna1535
@unknowna1535 7 жыл бұрын
Two things. mailService could just be a dependency of the banUser function. This would eliminate the need to pass in the mailService into makeUtils all together. Secondly, I would argue that the design is flawed in the first place with having banUser depend on emailing the user. That logic should obviously be part of controller logic and not the immediate responsibility of banUser itself.
@funfunfunction
@funfunfunction 7 жыл бұрын
I could have picked better examples that didn't distract you here. The purpose of this episode is primarily to show the mechanics of injection without classes, not DI architecture. I have other episodes for that (kzbin.info/www/bejne/Y5zTdoNqf8p4msU) I do, however, disagree that it's obvious that emailing should be delegated to the controller. It could be argued, but I think you're really overreaching when you say "obviously". First of all, this is a backend service doing emailing, so there is no controller or MVC pattern - so I'm assuming you actually mean "top-level code". Im assuming that you perhaps consider emailing to be a kind-of UI thing, notification a green bar in the UI, or outputting the result to the HTTP endpoint, but I don't think sending email is something you necessarily want to separate out of a banuser service. In this case, we want it to do everything involved in banning a user, and I think that's a perfectly reasonable design decision.
@unknowna1535
@unknowna1535 7 жыл бұрын
Im just saying I think think a ban user function should do exactly what it says. Ban a user. If you put emailing the user within the ban user function, for one it's harder to test because the ban user function has two responsibilities, emailing and updating the database or w/e to ban the user. Secondly, then you have to put additional logic in ban user if you ever later down the track what to send a different email body, or if you want to be able to ban a user without sending a email ect. Simply what I'm saying is that another piece of code (without the need for a controller, could be any http endpoint reciever) should first delegate to a ban user function, then a send email function. That's seperating concerns/single responsibility.
@falconmick
@falconmick 7 жыл бұрын
No coffee cup after intro >.
@NoC4k3
@NoC4k3 7 жыл бұрын
I just stopped dyeing my hairs blue 2weeks ago and now he starts. I always miss the current programmer trends :/
@emanonmax
@emanonmax 7 жыл бұрын
My first thought: inject a closure. Lets see how this works out
@chuuke
@chuuke 7 жыл бұрын
export const movementPlanner = ({ hands, feet, rocks, lions }) => hands.moveRocks(rocks).then(feet.runAwayFrom(lions));
@alvechy
@alvechy 7 жыл бұрын
Thanks a lot for your videos. With your videos I will find a job much quicker => will receive a salary => will become your patron.
@funfunfunction
@funfunfunction 7 жыл бұрын
+Alexander Swed that's my business model right there
@PerfectMakanju
@PerfectMakanju 7 жыл бұрын
Like your new hairstyle
@ancoopa
@ancoopa 7 жыл бұрын
Nice
@BasiC7786
@BasiC7786 7 жыл бұрын
i wonder how much more you can drift into the direction of functional programming before evolution brings you up to being a haskell-monk.
@jakelyall7180
@jakelyall7180 7 жыл бұрын
Maybe when evolution brings browsers up to haskell? He's using node, but JS is (still) more than just server-side...
@BasiC7786
@BasiC7786 7 жыл бұрын
I only talked about him as a Person, also: There are people that brought haskell to the browser(ghcjs, herculus.io). I wasn't just talking about server-side. Also with WebAssembly, soon (all) languages that compile to llvm will be web-ready.
@devmrin
@devmrin 7 жыл бұрын
Should've given us a 5 minute stare-at-my-hair-and-get-over-it video first!! Couldn't focus for the entirety of this video!!
@peterkulik5943
@peterkulik5943 5 жыл бұрын
So, you banned all users and notified only one. :)
@O_Eduardo
@O_Eduardo 7 жыл бұрын
Wisdom.
@threeone6012
@threeone6012 7 жыл бұрын
That hair!
@NeoChromer
@NeoChromer 7 жыл бұрын
Is it me, or are you a bit low energy in this one? kinda getting a bit "down" vibe from it.
@funfunfunction
@funfunfunction 7 жыл бұрын
+NeoChromer no that's correct, as I say in the video, I just got back from hosting Nordic.js and that it was one of the hardest things I've ever done :)
@NeoChromer
@NeoChromer 7 жыл бұрын
Aww, you could have taken a break, we would understand, thanks for making the video though !
@EduardoRFS
@EduardoRFS 7 жыл бұрын
ok we love you and your content, BUT EXPLAIN THAT HAIR
@EduardoRFS
@EduardoRFS 7 жыл бұрын
ok you explained, but why
@funfunfunction
@funfunfunction 7 жыл бұрын
+Eduardo RFS it's the nordic.js color! (Kind of)
@MaxDavydov-r2k
@MaxDavydov-r2k 7 жыл бұрын
Did you really get a tattoo? Show us on next video!
@funfunfunction
@funfunfunction 7 жыл бұрын
+Макс Давыдов I did!
@daniellaerachannel
@daniellaerachannel 7 жыл бұрын
the waste of coffee ...... :-(
@hellerbarde
@hellerbarde 7 жыл бұрын
At least he's reusing the intro now. So it's not newly wasted coffee in every video ^^
@funfunfunction
@funfunfunction 7 жыл бұрын
You would die if you visited the set of a video production. :) I also use fresh batteries in my sound recorder every shoot.
@whitelightflash
@whitelightflash 7 жыл бұрын
Recharge maybe?
Dependency Injection without classes - Fun Fun Function
22:07
Fun Fun Function
Рет қаралды 42 М.
Dependency Injection | Prime Reacts
28:34
ThePrimeTime
Рет қаралды 329 М.
escape in roblox in real life
00:13
Kan Andrey
Рет қаралды 74 МЛН
SCHOOLBOY. Мама флексит 🫣👩🏻
00:41
⚡️КАН АНДРЕЙ⚡️
Рет қаралды 7 МЛН
My daughter is creative when it comes to eating food #funny #comedy #cute #baby#smart girl
00:17
So Cute 🥰
00:17
dednahype
Рет қаралды 57 МЛН
The 'new' keyword - Object Creation in JavaScript P4 - FunFunFunction #50
24:34
From Dependency injection to dependency rejection - Mark Seemann
59:39
NDC Conferences
Рет қаралды 50 М.
GraphQL Basics - Fun Fun Function
48:24
Fun Fun Function
Рет қаралды 160 М.
Class keyword - Object Creation in JavaScript P7 - Fun Fun Function
17:26
How to Do 90% of What Plugins Do (With Just Vim)
1:14:03
thoughtbot
Рет қаралды 895 М.
Dependency INVERSION vs Dependency INJECTION in Python
17:51
ArjanCodes
Рет қаралды 159 М.
Generators in JavaScript - What, Why and How - FunFunFunction #34
27:20
Fun Fun Function
Рет қаралды 129 М.
Dependency Injection, The Best Pattern
13:16
CodeAesthetic
Рет қаралды 818 М.
Clean Code - Uncle Bob / Lesson 1
1:48:42
UnityCoin
Рет қаралды 1,9 МЛН
escape in roblox in real life
00:13
Kan Andrey
Рет қаралды 74 МЛН