Command Pattern - Design Patterns

  Рет қаралды 101,376

Web Dev Simplified

Web Dev Simplified

Күн бұрын

Пікірлер: 113
@Greedygoblingames
@Greedygoblingames 2 жыл бұрын
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.
@JokersLaught
@JokersLaught 4 жыл бұрын
This pattern makes even more sense in a static typed language where you can create a "Command" interface, which the Commands extend.
@thatsalot3577
@thatsalot3577 2 жыл бұрын
It'll be way easier to implement in typescript.
@abhayanavkar2243
@abhayanavkar2243 2 жыл бұрын
How can we implement this in java ? Especially the Calculator class
@bitgryph6450
@bitgryph6450 2 жыл бұрын
​@@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 :)
@xyzhang6053
@xyzhang6053 5 жыл бұрын
The clearest and illustrative way explaining design pattern I ever get.
@laysdong
@laysdong 5 жыл бұрын
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!
@WebDevSimplified
@WebDevSimplified 5 жыл бұрын
Thanks! I was a little worried doing a sponsorship that it might annoy people but I am glad that it doesn't bother you.
@laysdong
@laysdong 5 жыл бұрын
@@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!
@linhdo1738
@linhdo1738 5 жыл бұрын
Love your consistency!!! I gotta ring that bell to be notified when you post new videos :)
@Pspisripoff
@Pspisripoff 5 жыл бұрын
Better donate some cash! Help the coder out!
@heavyraindrops4750
@heavyraindrops4750 4 жыл бұрын
Thank you so much for showing this example without complicating it with threading as some examples do. This was very clearly explained!!
@GaneshSatputeAtPlus
@GaneshSatputeAtPlus 4 жыл бұрын
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".
@aanchalsharma8362
@aanchalsharma8362 4 жыл бұрын
I was thinking the same.
@MrEnsiferum77
@MrEnsiferum77 3 жыл бұрын
CQRS for example, is based on commands and events. Every modern event driven microservice architecture build the right way, use commands and events.
@paulodonovanmusic
@paulodonovanmusic 2 жыл бұрын
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
@SaqibMubarak
@SaqibMubarak 2 жыл бұрын
think about implementing chess game.
@deansprivatearchive
@deansprivatearchive 3 жыл бұрын
This is randomly getting recommended now!
@montebont
@montebont 2 жыл бұрын
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
@JoeWong81
@JoeWong81 5 жыл бұрын
Thanks a lot Kyle, this is the first time I've seen this.
@bordertone_5138
@bordertone_5138 5 жыл бұрын
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.
@WebDevSimplified
@WebDevSimplified 5 жыл бұрын
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.
@blokche_dev
@blokche_dev 5 жыл бұрын
Nice and clean explaination of the command pattern.
@ProgrammingwithPeter
@ProgrammingwithPeter 5 жыл бұрын
this was so clear and easy to understand! doing a great job!
@sonayr2657
@sonayr2657 4 жыл бұрын
Couldn't have made this concept anymore simple and easy to consume, great job!
@randymartin9040
@randymartin9040 3 ай бұрын
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.
@paulodonovanmusic
@paulodonovanmusic 2 жыл бұрын
I learnt so much today, thanks Kyle!
@AsciiKing
@AsciiKing 2 жыл бұрын
Nice work. Very clearly explained, dude.
@karnpratapsingh8860
@karnpratapsingh8860 3 жыл бұрын
great explanation brother!
@adeaf3396
@adeaf3396 2 жыл бұрын
Thanks a lot man, such a great job, cheers!
@MrMarkgyuro
@MrMarkgyuro 5 жыл бұрын
this was really clear and helpful : ) ! thank you !
@Victor_Marius
@Victor_Marius 3 жыл бұрын
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?
@CottidaeSEA
@CottidaeSEA 2 жыл бұрын
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.
@heavencanceller1863
@heavencanceller1863 3 жыл бұрын
You explained this perfectly. Thank you
@ayushdedhia25
@ayushdedhia25 5 жыл бұрын
Hey Bro are you using any extension for not using semicolons...please tell🤔🤔🤔🤔
@WebDevSimplified
@WebDevSimplified 5 жыл бұрын
Nope. Semi colons are optional in JS
@talfaran5849
@talfaran5849 3 жыл бұрын
@@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.
@lutaseb
@lutaseb 3 жыл бұрын
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
@CottidaeSEA
@CottidaeSEA 2 жыл бұрын
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.
@ksrele
@ksrele 5 жыл бұрын
How do you record sound? It sounds like some "noise reduction" option is enabled and it destroys the sound...
@WebDevSimplified
@WebDevSimplified 5 жыл бұрын
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.
@ksrele
@ksrele 5 жыл бұрын
@@WebDevSimplified Just follow this instructions but turn off all options. techtalk.currys.co.uk/gadgets/smart-home/how-to-reduce-microphone-noise/
@misterl8129
@misterl8129 2 жыл бұрын
this video was amazing
@manzourabdalla2279
@manzourabdalla2279 5 жыл бұрын
Thank you for everything Incredible videos, keep going
@xyzhang6053
@xyzhang6053 5 жыл бұрын
Do more on design pattern, please!
@17corteznumber
@17corteznumber 8 ай бұрын
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?
@cliffordowusuamponsah9532
@cliffordowusuamponsah9532 3 жыл бұрын
One of my favorite youtubers so far. Blessings Kyle. I have been following the series and it’s great!!!
@elijahmuraoka
@elijahmuraoka 2 жыл бұрын
What’s the benefit to using “const” rather than an “int” or “double”
@CottidaeSEA
@CottidaeSEA 2 жыл бұрын
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.
@WarpingWombat
@WarpingWombat 4 жыл бұрын
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
@alimertc
@alimertc 2 жыл бұрын
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().
@stefan4800
@stefan4800 5 жыл бұрын
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. ;)
@CottidaeSEA
@CottidaeSEA 2 жыл бұрын
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.
@xBZZZZyt
@xBZZZZyt 3 жыл бұрын
09:45 just use functions to avoid duplication
@shawnnosaurus
@shawnnosaurus 3 жыл бұрын
Combined with statechart machines and you can make some impressive systems.
@jeromesnail
@jeromesnail 3 жыл бұрын
Every pattern is your favorite 😁
@GoonCity777
@GoonCity777 3 жыл бұрын
I mean, you would be a top computer teacher in a university or bootcamp
@roytouw4374
@roytouw4374 2 жыл бұрын
Clear explanation, only this seems like a lot of overhead compared to using the functional style of composing curried functions?
@Dragon20C
@Dragon20C 3 жыл бұрын
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.
@zkiez2995
@zkiez2995 4 жыл бұрын
What are u using to code??
@Jonathan-qz9td
@Jonathan-qz9td 4 жыл бұрын
He uses vscode
@Lyrik-Klinge
@Lyrik-Klinge 5 жыл бұрын
you made a good job of it!
@QQ-kh6uf
@QQ-kh6uf 5 жыл бұрын
Absolutely splendid!
@idev6775
@idev6775 4 жыл бұрын
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.
@thatsalot3577
@thatsalot3577 2 жыл бұрын
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.
@TheAceInfinity
@TheAceInfinity 3 жыл бұрын
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.
@jivanmainali1742
@jivanmainali1742 5 жыл бұрын
I am using heroku so is there any benefits of using Atlantic hosting? Suggest me
@WebDevSimplified
@WebDevSimplified 5 жыл бұрын
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.
@MrXception007
@MrXception007 4 жыл бұрын
Which mic you are using?
@pranavpatil5849
@pranavpatil5849 5 жыл бұрын
Hey ..can u tell which design pattern is used in Modern web React-redux application?
@blu3_enjoy
@blu3_enjoy 2 жыл бұрын
Thank you
@linkarysl9938
@linkarysl9938 2 жыл бұрын
great, thx!
@tacowilco7515
@tacowilco7515 5 жыл бұрын
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 :-)
@WebDevSimplified
@WebDevSimplified 5 жыл бұрын
That would be ideal actually. Nice point.
@pascalrenner4320
@pascalrenner4320 5 жыл бұрын
Yes, using fluent interfaces in this example would be great and make combinations like AddThenMultiplay like that unnecessary.
@dariogabalec13
@dariogabalec13 4 жыл бұрын
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.
@muchograndeyolatengo
@muchograndeyolatengo 3 жыл бұрын
@@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).
@CottidaeSEA
@CottidaeSEA 2 жыл бұрын
​@@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.
@susanthawarnapura
@susanthawarnapura 5 жыл бұрын
nice explanation
@panchcw
@panchcw 3 жыл бұрын
could do video for flywieght pattern
@priyantanugupta7643
@priyantanugupta7643 3 жыл бұрын
Loved it
@aotechdev
@aotechdev 5 жыл бұрын
Thanks Keil
@jivanmainali1742
@jivanmainali1742 5 жыл бұрын
Always impressive
@GoldenPanthersLax
@GoldenPanthersLax 5 жыл бұрын
Great video, for the history array you should try out concat or the spread operator to keeps things immutable
@pooyadehghan17
@pooyadehghan17 4 жыл бұрын
Just love it ...
@Trek_Tales
@Trek_Tales 5 жыл бұрын
Bro can you please explain me function closures in JavaScript please ..please ..please..
@eddiejaoude
@eddiejaoude 5 жыл бұрын
Design patterns 👍💪🤓
@aditya234567
@aditya234567 4 жыл бұрын
Isnt this memento pattern???
@ransabalon
@ransabalon 5 жыл бұрын
can you please blink? hahaha
@lastdecember2496
@lastdecember2496 5 жыл бұрын
SaveExit() { this.save(); this.exit(); }
@xBZZZZyt
@xBZZZZyt 3 жыл бұрын
add undo limit because calculator will use more RAM every time command is executed
@MOUNIROU60
@MOUNIROU60 4 жыл бұрын
this is kind of command pattern with integrated factory pattern
@reignover17
@reignover17 3 жыл бұрын
indeed the execute() method shouldnt receive any parameter
@TheKillermob13
@TheKillermob13 4 жыл бұрын
did u just changed your shirt
@user-uh3zr7mo4i
@user-uh3zr7mo4i 5 жыл бұрын
why arent your eyes blinking?
@neoX12000
@neoX12000 5 жыл бұрын
Hey everyone had a awesome life until webassembly comes
@ДенисБосый-ю7р
@ДенисБосый-ю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.
@mosup5007
@mosup5007 4 жыл бұрын
I clicked the video to see your spin. why didn't you do it.
@WebDevSimplified
@WebDevSimplified 4 жыл бұрын
I only ever did it in one video
@mosup5007
@mosup5007 4 жыл бұрын
@@WebDevSimplified it was about positioning in css and it was a good one. I wanted to learn a little a bout front-end.
@WebDevSimplified
@WebDevSimplified 4 жыл бұрын
I have a bunch of videos on the frontend on my channel you can checkout. Unfortunately, none have a chair spin though.
@hansalucas
@hansalucas 2 жыл бұрын
too much staring o.o
@deansprivatearchive
@deansprivatearchive 3 жыл бұрын
83th
@deansprivatearchive
@deansprivatearchive 3 жыл бұрын
Weird. 2 years ago.
@tech-andgar
@tech-andgar 5 жыл бұрын
🤯👌
@CryptoRootz
@CryptoRootz 5 жыл бұрын
hella fucking confusing.... break this shit down even further bro....
Single Responsibility Principle Explained - SOLID Design Principles
6:17
Web Dev Simplified
Рет қаралды 194 М.
Builder Pattern - Design Patterns
10:49
Web Dev Simplified
Рет қаралды 138 М.
Chain Game Strong ⛓️
00:21
Anwar Jibawi
Рет қаралды 41 МЛН
To Brawl AND BEYOND!
00:51
Brawl Stars
Рет қаралды 17 МЛН
Cat mode and a glass of water #family #humor #fun
00:22
Kotiki_Z
Рет қаралды 42 МЛН
Command Pattern - Design Patterns (ep 7)
39:12
Christopher Okhravi
Рет қаралды 274 М.
How To Build Feature Flags Like A Senior Dev In 20 Minutes
20:33
Web Dev Simplified
Рет қаралды 108 М.
10 Design Patterns Explained in 10 Minutes
11:04
Fireship
Рет қаралды 2,4 МЛН
Null Object Pattern - Design Patterns
10:24
Web Dev Simplified
Рет қаралды 82 М.
5 Design Patterns Every Engineer Should Know
11:51
Traversy Media
Рет қаралды 943 М.
Discord Made The Coolest CSS Only Input Animation
17:48
Web Dev Simplified
Рет қаралды 60 М.
Why Is Array/Object Destructuring So Useful And How To Use It
13:24
Web Dev Simplified
Рет қаралды 431 М.
The CSS Display Property is Changing Forever
15:20
Web Dev Simplified
Рет қаралды 70 М.
Dependency Inversion Principle Explained - SOLID Design Principles
13:00
Web Dev Simplified
Рет қаралды 164 М.
Chain Game Strong ⛓️
00:21
Anwar Jibawi
Рет қаралды 41 МЛН