This pattern makes even more sense in a static typed language where you can create a "Command" interface, which the Commands extend.
@thatsalot35772 жыл бұрын
It'll be way easier to implement in typescript.
@abhayanavkar22432 жыл бұрын
How can we implement this in java ? Especially the Calculator class
@bitgryph64502 жыл бұрын
@@abhayanavkar2243 You can use Stack commandStack = new Stack(). Declaring it this way will allow you to push() every object that implements interface Command. And when you'll want to use undo() write: Command last_command = commandStack.pop(); Hope that helps :)
@Greedygoblingames2 жыл бұрын
Ideally "undo" shouldn't take any parameters and the command class should be immutable, storing the "currentValue" itself, so undo is assured to reverse the original command.
@xyzhang60535 жыл бұрын
The clearest and illustrative way explaining design pattern I ever get.
@laysdong5 жыл бұрын
Glad to see some sponsorship on your videos. These are hands down the best js videos ive ever seen, and you deserve to be compensated for them. Thanks!
@WebDevSimplified5 жыл бұрын
Thanks! I was a little worried doing a sponsorship that it might annoy people but I am glad that it doesn't bother you.
@laysdong5 жыл бұрын
@@WebDevSimplified Yep not an annoyance at all. As long as the sponsorship ads are fairly relevant and concise(60-90 seconds is probably about the longest a plug should last imo) then you're golden. Keep up the awesome work. You've taught me a ton!
@heavyraindrops47504 жыл бұрын
Thank you so much for showing this example without complicating it with threading as some examples do. This was very clearly explained!!
@linhdo17385 жыл бұрын
Love your consistency!!! I gotta ring that bell to be notified when you post new videos :)
@Pspisripoff5 жыл бұрын
Better donate some cash! Help the coder out!
@GaneshSatputeAtPlus4 жыл бұрын
I get how the pattern is implemented, but I'm not sure what problem does it solve. The "why" is more important than "what" or "how".
@aanchalsharma83623 жыл бұрын
I was thinking the same.
@MrEnsiferum773 жыл бұрын
CQRS for example, is based on commands and events. Every modern event driven microservice architecture build the right way, use commands and events.
@paulodonovanmusic2 жыл бұрын
Maybe it helps to think about the three examples given (calculator, save/save&exit/exit, bold/etc text), or any situation where you would need to manage the state of a variety of ‘tools’, and how much more complicated our code might be to do it if we didn’t know this pattern
@SaqibMubarak2 жыл бұрын
think about implementing chess game.
@sonayr26574 жыл бұрын
Couldn't have made this concept anymore simple and easy to consume, great job!
@bordertone_51385 жыл бұрын
But in that way maybe you eventually have to pay extra attention for the undo part ? Because if a function is sort of irreversable (i mean, in case you can't track of the original value just by doing the other way around) e.g in the typical case user put 0 as a multiplier. And because the undo part is coded in a bit of hard coded way, so there could be many cases you can't come back to the initial value and then you have to add extra code to fix it although it doesn't necessarily hurt the worth of pattern itself. Just a thought.
@WebDevSimplified5 жыл бұрын
That is a really good point. In cases like these one thing you can do is store the previous value inside the command class for the undo operation.
@montebont2 жыл бұрын
Lovely! I've been around for a bit and it reminds me of the postFix notation in Forth, SmallTalk and a few other languages. What it comes down to is that you first push values (operands) onto a stack followed by the operator. So rather "3 5 +" then "3 + 5". In this example, "3 5 +" pushes the numbers onto the stack because they are numbers/operands. The "+" is recognized as an operator. and It'll add the 2 numbers by pulling them from the stack and pushing the result "5". I am not sure if this was actually implemented in SmallTalk but you can easily manage history by adding markers to the stack in the same way as try/catch (and a few other "GOTO's in disguise") work. Stacks are just arrays of objects and can be easily inplemented in Javascript ;-) Anyway: thanks for all your efforts to share you knowledge in a very accessible way! Ed
@deansprivatearchive3 жыл бұрын
This is randomly getting recommended now!
@JoeWong815 жыл бұрын
Thanks a lot Kyle, this is the first time I've seen this.
@blokche_dev5 жыл бұрын
Nice and clean explaination of the command pattern.
@vivekborade61364 жыл бұрын
Hi I love you video the way u built it. Thks for all u efforts take to explain the concept.
@ProgrammingwithPeter5 жыл бұрын
this was so clear and easy to understand! doing a great job!
@xyzhang60535 жыл бұрын
Do more on design pattern, please!
@randymartin90402 ай бұрын
This is sick! I definitely need to practice it as it's still really confusing, but you did a great job explaining it and how it could be used sort of like Lego or higher order functions (I think that's where you have a function that calls other functions right? :P ) Still pretty new. Thanks for your great videos.
@roytouw43742 жыл бұрын
Clear explanation, only this seems like a lot of overhead compared to using the functional style of composing curried functions?
@paulodonovanmusic2 жыл бұрын
I learnt so much today, thanks Kyle!
@17corteznumber7 ай бұрын
Hi Kyle, thank you for the content!! I noticed that you didn't build a base command class that could be extended to child commands. Would you suggest implementing a base command with a value and execute and undo methods?
@heavencanceller18633 жыл бұрын
You explained this perfectly. Thank you
@TheAceInfinity3 жыл бұрын
An undo function that needs to be cognizant of the previous operation isn't really an undo however... There are some commands that you potentially cannot undo either (i.e. bitshifting where you've lost bits). A far better demonstration would've been to cache the original value, and it would've also saved on computations.
@AsciiKing2 жыл бұрын
Nice work. Very clearly explained, dude.
@lutaseb3 жыл бұрын
Back then i did not learn Command the way you explain, it had just en execute() method, no other method, no parameters, everything was wrapped before the call, which is very similar to the implementation of Runnable in java. Still, I had to implement some cancel operation, and I did not need to divide a value but just return the initial value that was passed on at the construction time
@CottidaeSEA2 жыл бұрын
The command pattern can be implemented pretty much however you want. The main thing to keep in mind is that the interface should be uniform; in fact, if you have access to interfaces in the language you're using, you should use them. That way you can add instructions that the executing class can use. What you mentioned regarding just returning the original value on cancel/undo is the better approach as it reduces computational power. In fact, I slightly disagree with what was done in this video. If using the principle you mentioned, it would be enough to simply have one execute method, the calculator itself can worry about dealing with the history, not the commands.
@stefan48005 жыл бұрын
Good idea is to use Dependency Injection, creating for example Device interface, so you can have multiple devices which are implementing the interface, like Calculator, Remote, etc. You can create the class ExecuteCommand, with constructor require the interface Device, so you can do something like this: Class ExecuteCommand { constructor(Device insertDevice) execute(DoCommand); undo(UndoCommand); } executeCalcurator = new ExecuteCommand(new Calculator) executeRemote = new ExecuteCommand(new Remote) executeCalcurator->execute(new AddCommand(10)) executeCalcurator->undo(new SubtractCommand(10)) executeRemote->execute(new AddVolume(10)) executeRemote->undo(new SubtractVolume(10)) etc, etc... Note: My pseudo code reminiscent on PHP, the language I usually use, so sorry about that. ;)
@CottidaeSEA2 жыл бұрын
The calculator itself should worry about the history. I don't feel like the commands themselves should have to think much of it. However, even then it should be enough to remember the initial state, which should be set during execute. If you want to be proper, the execute command should also throw an error if it has already been run, that way you can ensure the state remains untouched.
@GoonCity7773 жыл бұрын
I mean, you would be a top computer teacher in a university or bootcamp
@MrMarkgyuro5 жыл бұрын
this was really clear and helpful : ) ! thank you !
@shawnnosaurus3 жыл бұрын
Combined with statechart machines and you can make some impressive systems.
@jeromesnail3 жыл бұрын
Every pattern is your favorite 😁
@karnpratapsingh88603 жыл бұрын
great explanation brother!
@cliffordowusuamponsah95323 жыл бұрын
One of my favorite youtubers so far. Blessings Kyle. I have been following the series and it’s great!!!
@idev67753 жыл бұрын
Hello, thank you so much! But you don't need to creating so many class as AddCommand, DivideCommand, etc You can create Command class and code as: class Command { constructor(value, method) { this.value = value; this.method = method; } execute(currentValue) { return { add: currentValue + this.value, subtract: currentValue - this.value, multiple: currentValue * this.value, divide: currentValue / this.value, }[this.method]; } undo(currentValue) { return { add: currentValue - this.value, subtract: currentValue + this.value, multiple: currentValue / this.value, divide: currentValue * this.value, }[this.method]; } } And then const calculator = new Calculator(); calculator.executeCommand(new Command(10, 'add')); console.log(calculator.value); calculator.undo(); If it is stupid... please comment below. Thank for reading.
@thatsalot35772 жыл бұрын
That's a really great way of simplifying the code But the problem is, your code doesn't follow open-close SOLID principle which means it's not open for extensions For eg : you do have all the methods for doing basic arithmetic like add, subtract, etc... But let's say you need to add square root as an option or raised to power or floor function or any other complicated function that'll take about 10+ lines of code Your calculator class would start disobeying the single dependency SOLID principle which states each class(or file or function) should do only one complicated thing.
@pinguincoder4 жыл бұрын
For doing save and exit i find this kinda overengineered. You could also just call Save () and then Exit() inside the Save&Exit and you would not have to duplicate anything. Also for Save and Exit.. Providing an undo is not really something that's is useful and should be done
@alimertc2 жыл бұрын
Well, dont take it literally. Its an example to show you that you can compose commands. SaveExit command can also do some additonal stuff, e.g cleanup(); save(); exit().
@adeaf33962 жыл бұрын
Thanks a lot man, such a great job, cheers!
@misterl81292 жыл бұрын
this video was amazing
@manzourabdalla22795 жыл бұрын
Thank you for everything Incredible videos, keep going
@Dragon20C3 жыл бұрын
what are the possibilities, I got told this is a good way of controlling what type of action/function I want to be called at a specific times, for example a turn base system.
@Victor_Marius3 жыл бұрын
But what if the command is not reversible? Like for example after scaling an image down you cannot scale it up because you lose information. Should then be used a history of state there, and for undo you pick the last state of your object / application - but this may increase memory usage for large objects like images / videos?
@CottidaeSEA2 жыл бұрын
Just save the initial state rather than try to calculate the original state. That's a bad idea regardless of the required computational power as it can lead to other side effects such as floating point variances, funky things happening to strings due to encoding, etc. It's better to instead just save the state somehow.
@QQ-kh6uf5 жыл бұрын
Absolutely splendid!
@blu3_enjoy2 жыл бұрын
Thank you
@GoldenPanthersLax5 жыл бұрын
Great video, for the history array you should try out concat or the spread operator to keeps things immutable
@elijahmuraoka2 жыл бұрын
What’s the benefit to using “const” rather than an “int” or “double”
@CottidaeSEA2 жыл бұрын
There is no int or double in JavaScript. A const cannot be reassigned, modified if an object however. There are two alternatives, let and var. Most favor let these days, but var can ensure it cannot be deleted and as such will technically keep being defined even though the value itself can be undefined. They also have different scope rules. But to answer your question; there is no reason not to, it just doesn't exist in JavaScript.
@Lyrik-Klinge5 жыл бұрын
you made a good job of it!
@susanthawarnapura5 жыл бұрын
nice explanation
@tacowilco75155 жыл бұрын
I feel like executeCommand() and undo() had to return 'this'. So you could do: calculator.executeCommand(new AddCommand(10)) .executeCommand(new MutliplyCommand(2)) .undo(); But that's just me being picky on random youtube videos :-)
@WebDevSimplified5 жыл бұрын
That would be ideal actually. Nice point.
@pascalrenner43204 жыл бұрын
Yes, using fluent interfaces in this example would be great and make combinations like AddThenMultiplay like that unnecessary.
@dariogabalec134 жыл бұрын
I tried this solution and it works. The problem with this approach, in my humble opinion, is that violates the single responsibility principle of SOLID. Because executeCommand() shouldn't return an object, just should execute a command.
@muchograndeyolatengo3 жыл бұрын
@@dariogabalec13 If I'm not mistaken then Java Streams and C# LINQ also is in violation. Or is it the semantics of "execute" you object to? That doesn't seem like a OOP issue to me, but about naming conventions (and can be easily fixed).
@CottidaeSEA2 жыл бұрын
@@muchograndeyolatengo It is not an OOP issue, returning the original instance is fairly common in OOP. However, it is most commonly used for things like the factory pattern. SOLID however is a different story. While I do not believe SOLID is technically against this sort of chaining, the issues is rather that the execute method then would have multiple uses, or responsibilities as Dario put it. While not necessarily multiple responsibilities in my opinion, it allows for potentially complicated chaining which *does* go against the principles of SOLID. I don't think you necessarily have to strictly follow a principle, it is just that, a principle. It is something you should follow where it makes sense, but it is not a law. In some cases not following a set principle is the best approach, other times it is not, which is why experience is necessary to judge the situation properly. In this case I absolutely agree that it should not return the instance. If multiple commands are to be chained, it is in my opinion better to simply loop through an array. As for Java Streams, they don't necessarily violate SOLID, but their usage can certainly do. The issue with streams and lambdas in Java is that they sometimes become very long and bulky, making them hard to read. As a result it can be better to just assign the return value to a variable which you then use on the following row. Depending on what you're doing in the function, it should follow those principles and all is fine. Besides, if you split literally everything into separate methods, you'll have a massive hell to work through, not to mention naming the damn things.
@aotechdev5 жыл бұрын
Thanks Keil
@linkarysl99382 жыл бұрын
great, thx!
@ayushdedhia255 жыл бұрын
Hey Bro are you using any extension for not using semicolons...please tell🤔🤔🤔🤔
@WebDevSimplified5 жыл бұрын
Nope. Semi colons are optional in JS
@talfaran58493 жыл бұрын
@@WebDevSimplified Try to use them as a standard because you very often have to use them with TypeScript. that said - u can use Prettier connected to an Eslint rule that will add the semi-columns for you.
@ksrele5 жыл бұрын
How do you record sound? It sounds like some "noise reduction" option is enabled and it destroys the sound...
@WebDevSimplified5 жыл бұрын
I am using OBS, but I agree something sounds off. I really need to sit down for an hour or so with someone who knows audio really well and go through my setup.
@ksrele5 жыл бұрын
@@WebDevSimplified Just follow this instructions but turn off all options. techtalk.currys.co.uk/gadgets/smart-home/how-to-reduce-microphone-noise/
@MrXception0074 жыл бұрын
Which mic you are using?
@xBZZZZyt3 жыл бұрын
09:45 just use functions to avoid duplication
@priyantanugupta76433 жыл бұрын
Loved it
@pranavpatil58495 жыл бұрын
Hey ..can u tell which design pattern is used in Modern web React-redux application?
@zkiez29954 жыл бұрын
What are u using to code??
@Jonathan-qz9td4 жыл бұрын
He uses vscode
@jivanmainali17425 жыл бұрын
Always impressive
@jivanmainali17425 жыл бұрын
I am using heroku so is there any benefits of using Atlantic hosting? Suggest me
@WebDevSimplified5 жыл бұрын
Atlantic is cheaper by a lot for the power you get but it requires you to do more devops yourself since it is just a ser we and you have to manage everything yourself. It is great for learning devops.
@pooyadehghan174 жыл бұрын
Just love it ...
@xBZZZZyt3 жыл бұрын
add undo limit because calculator will use more RAM every time command is executed
@reignover173 жыл бұрын
indeed the execute() method shouldnt receive any parameter
@aditya2345673 жыл бұрын
Isnt this memento pattern???
@panchcw3 жыл бұрын
could do video for flywieght pattern
@lastdecember24965 жыл бұрын
SaveExit() { this.save(); this.exit(); }
@MOUNIROU604 жыл бұрын
this is kind of command pattern with integrated factory pattern
@Trek_Tales5 жыл бұрын
Bro can you please explain me function closures in JavaScript please ..please ..please..
@eddiejaoude5 жыл бұрын
Design patterns 👍💪🤓
@ДенисБосый-ю7р2 жыл бұрын
It is really strange to explain pattern without abstract diagram, it could be more understandable if you had shown us an UML diagram.
@neoX120005 жыл бұрын
Hey everyone had a awesome life until webassembly comes
@TheKillermob134 жыл бұрын
did u just changed your shirt
@user-uh3zr7mo4i5 жыл бұрын
why arent your eyes blinking?
@mosup50074 жыл бұрын
I clicked the video to see your spin. why didn't you do it.
@WebDevSimplified4 жыл бұрын
I only ever did it in one video
@mosup50074 жыл бұрын
@@WebDevSimplified it was about positioning in css and it was a good one. I wanted to learn a little a bout front-end.
@WebDevSimplified4 жыл бұрын
I have a bunch of videos on the frontend on my channel you can checkout. Unfortunately, none have a chair spin though.
@hansalucas2 жыл бұрын
too much staring o.o
@tech-andgar5 жыл бұрын
🤯👌
@ransabalon5 жыл бұрын
can you please blink? hahaha
@deansprivatearchive3 жыл бұрын
83th
@deansprivatearchive3 жыл бұрын
Weird. 2 years ago.
@CryptoRootz5 жыл бұрын
hella fucking confusing.... break this shit down even further bro....